diff --git a/.gitignore b/.gitignore
index 88cf776..b1e7c27 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@
 *.suo
 *.targets
 *.user
+*.vc.opendb
 *.vcproj
 *.vcxproj
 *.vcxproj.filters
diff --git a/DEPS b/DEPS
index 44928ad..28c1c95 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '8377e80951326f94714b31ede711cd0757d37fcd',
+  'skia_revision': 'fcff08c8301b1ca08eee20911d0df5fb9db41156',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'b244d40e7ae7a73f2ceb08f0032519d66049c15f',
+  'v8_revision': '205085f926d00f4ea6e756bf251c54313d61e9d8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -59,7 +59,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '955930dce7e4b5c764cdd34b134baea4207de523',
+  'pdfium_revision': '34bb6c58fe60206a08dc0a1f37b7cfe83e8c762c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -106,7 +106,7 @@
 
 deps = {
   'src/breakpad/src':
-   Var('chromium_git') + '/breakpad/breakpad/src.git' + '@' + 'b0383cd494e736720d237d61af2912bb60960cd8',
+   Var('chromium_git') + '/breakpad/breakpad/src.git' + '@' + '615a6b0e2b376e3ae946972a52ef897bf6daaff3',
 
   'src/buildtools':
    Var('chromium_git') + '/chromium/buildtools.git' + '@' +  Var('buildtools_revision'),
@@ -390,7 +390,7 @@
 
     # For Linux and Chromium OS.
     'src/third_party/cros_system_api':
-     Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'ecbd58958f83b7b32068f328ddd605ba732c7052',
+     Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'ed198c46f73e67d9a494c3c0623e3ba16e4da5e8',
 
     # Note that this is different from Android's freetype repo.
     'src/third_party/freetype2/src':
diff --git a/WATCHLISTS b/WATCHLISTS
index 53f8b72..d28a6a2c 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -10,6 +10,9 @@
 
 {
   'WATCHLIST_DEFINITIONS': {
+    'about_flags': {
+      'filepath': 'chrome/browser/about_flags\.cc'
+    },
     'accelerator_table': {
       'filepath': 'ash/accelerators/accelerator_table\.cc' \
                   '|chrome/browser/ui/views/accelerator_table\.cc',
@@ -497,7 +500,9 @@
                   '|chrome/browser/extensions/api/metrics_private/'\
                   '|chrome/browser/ui/webui/metrics_handler'\
                   '|content/browser/user_metrics.cc'\
+                  '|components/metrics/'\
                   '|components/rappor/'\
+                  '|components/variations/'\
                   '|content/public/browser/user_metrics.h'\
                   # Exclude XML files; in particular, histograms.xml.
                   '|tools/metrics/[^.]*([.](?!xml$).*)?$',
@@ -1201,6 +1206,7 @@
   },
 
   'WATCHLISTS': {
+    'about_flags': ['asvitkine+watch@chromium.org'],
     'accelerator_table': ['derat+watch@chromium.org',
                           'yusukes+watch@chromium.org'],
     'accessibility': ['aboxhall+watch@chromium.org',
diff --git a/android_webview/android_webview_tests.gypi b/android_webview/android_webview_tests.gypi
index 908bce3..14c90ca 100644
--- a/android_webview/android_webview_tests.gypi
+++ b/android_webview/android_webview_tests.gypi
@@ -34,6 +34,7 @@
           '<(asset_location)/video.mp4',
           '<(asset_location)/visual_state_during_fullscreen_test.html',
           '<(asset_location)/visual_state_waits_for_js_test.html',
+          '<(asset_location)/visual_state_waits_for_js_detached_test.html',
           '<(asset_location)/visual_state_on_page_commit_visible_test.html',
           '<@(snapshot_additional_input_paths)',
         ],
@@ -61,6 +62,7 @@
             '<(java_in_dir)/assets/video.mp4',
             '<(java_in_dir)/assets/visual_state_during_fullscreen_test.html',
             '<(java_in_dir)/assets/visual_state_waits_for_js_test.html',
+            '<(java_in_dir)/assets/visual_state_waits_for_js_detached_test.html',
             '<(java_in_dir)/assets/visual_state_on_page_commit_visible_test.html',
             '<@(snapshot_copy_files)',
           ],
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index fa9ea17..c61f2e1 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -30,8 +30,6 @@
 
 const double kEpsilon = 1e-8;
 
-const int64 kFallbackTickTimeoutInMilliseconds = 100;
-
 // Used to calculate memory allocation. Determined experimentally.
 const size_t kMemoryMultiplier = 20;
 const size_t kBytesPerPixel = 4;
@@ -103,8 +101,7 @@
       max_page_scale_factor_(0.f),
       on_new_picture_enable_(false),
       clear_view_(false),
-      offscreen_pre_raster_(false),
-      fallback_tick_pending_(false) {}
+      offscreen_pre_raster_(false) {}
 
 BrowserViewRenderer::~BrowserViewRenderer() {
 }
@@ -225,12 +222,6 @@
   shared_renderer_state_.SetScrollOffsetOnUI(last_on_draw_scroll_offset_);
   hardware_enabled_ = true;
 
-  return CompositeHw();
-}
-
-bool BrowserViewRenderer::CompositeHw() {
-  CancelFallbackTick();
-
   ReturnResourceFromParent();
   UpdateMemoryPolicy();
 
@@ -270,14 +261,16 @@
                      transform_for_tile_priority, offscreen_pre_raster_,
                      parent_draw_constraints.is_layer));
 
-  // Uncommitted frame can happen with consecutive fallback ticks.
+  // If we haven't received a kModeSync functor call since the last
+  // CompositeHw then we need to discard the resources that are being
+  // held onto by the previously prepared frame.
   ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI());
   shared_renderer_state_.SetCompositorFrameOnUI(child_frame.Pass());
   return true;
 }
 
 void BrowserViewRenderer::UpdateParentDrawConstraints() {
-  PostInvalidateWithFallback();
+  PostInvalidate();
   ParentCompositorDrawConstraints parent_draw_constraints =
       shared_renderer_state_.GetParentDrawConstraintsOnUI();
   client_->ParentDrawConstraintsUpdated(parent_draw_constraints);
@@ -351,7 +344,7 @@
 
   clear_view_ = true;
   // Always invalidate ignoring the compositor to actually clear the webview.
-  PostInvalidateWithFallback();
+  PostInvalidate();
 }
 
 void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) {
@@ -649,80 +642,11 @@
 void BrowserViewRenderer::PostInvalidate() {
   TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate",
                        TRACE_EVENT_SCOPE_THREAD);
-  PostInvalidateWithFallback();
-}
-
-void BrowserViewRenderer::PostInvalidateWithFallback() {
-  // Always call view invalidate. We rely the Android framework to ignore the
-  // invalidate when it's not needed such as when view is not visible.
   client_->PostInvalidate();
-
-  // Stop fallback ticks when one of these is true.
-  // 1) Webview is paused. Also need to check we are not in clear view since
-  // paused, offscreen still expect clear view to recover.
-  // 2) If we are attached to window and the window is not visible (eg when
-  // app is in the background). We are sure in this case the webview is used
-  // "on-screen" but that updates are not needed when in the background.
-  bool throttle_fallback_tick =
-      (is_paused_ && !clear_view_) || (attached_to_window_ && !window_visible_);
-
-  if (throttle_fallback_tick || fallback_tick_pending_)
-    return;
-
-  DCHECK(post_fallback_tick_.IsCancelled());
-  DCHECK(fallback_tick_fired_.IsCancelled());
-
-  post_fallback_tick_.Reset(base::Bind(&BrowserViewRenderer::PostFallbackTick,
-                                       base::Unretained(this)));
-  ui_task_runner_->PostTask(FROM_HERE, post_fallback_tick_.callback());
-  fallback_tick_pending_ = true;
-}
-
-void BrowserViewRenderer::CancelFallbackTick() {
-  post_fallback_tick_.Cancel();
-  fallback_tick_fired_.Cancel();
-  fallback_tick_pending_ = false;
-}
-
-void BrowserViewRenderer::PostFallbackTick() {
-  DCHECK(fallback_tick_fired_.IsCancelled());
-  TRACE_EVENT0("android_webview", "BrowserViewRenderer::PostFallbackTick");
-  post_fallback_tick_.Cancel();
-  fallback_tick_fired_.Reset(base::Bind(&BrowserViewRenderer::FallbackTickFired,
-                                        base::Unretained(this)));
-  ui_task_runner_->PostDelayedTask(
-      FROM_HERE, fallback_tick_fired_.callback(),
-      base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds));
-}
-
-void BrowserViewRenderer::FallbackTickFired() {
-  TRACE_EVENT0("android_webview", "BrowserViewRenderer::FallbackTickFired");
-  // This should only be called if OnDraw or DrawGL did not come in time, which
-  // means fallback_tick_pending_ must still be true.
-  DCHECK(fallback_tick_pending_);
-  fallback_tick_fired_.Cancel();
-  fallback_tick_pending_ = false;
-  if (compositor_) {
-    if (hardware_enabled_ && !size_.IsEmpty()) {
-      CompositeHw();
-    } else {
-      ForceFakeCompositeSW();
-    }
-  }
-}
-
-void BrowserViewRenderer::ForceFakeCompositeSW() {
-  DCHECK(compositor_);
-  SkBitmap bitmap;
-  bitmap.allocN32Pixels(1, 1);
-  bitmap.eraseColor(0);
-  SkCanvas canvas(bitmap);
-  CompositeSW(&canvas);
 }
 
 bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) {
   DCHECK(compositor_);
-  CancelFallbackTick();
   ReturnResourceFromParent();
   return compositor_->DemandDrawSw(canvas);
 }
@@ -744,8 +668,6 @@
   base::StringAppendF(&str, "window_visible: %d ", window_visible_);
   base::StringAppendF(&str, "dip_scale: %f ", dip_scale_);
   base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_);
-  base::StringAppendF(&str, "fallback_tick_pending: %d ",
-                      fallback_tick_pending_);
   base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str());
   base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_);
   base::StringAppendF(&str,
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h
index 21c28c8..4d31689 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/browser_view_renderer.h
@@ -120,18 +120,12 @@
  private:
   void SetTotalRootLayerScrollOffset(const gfx::Vector2dF& new_value_dip);
   bool CanOnDraw();
-  // Posts an invalidate with fallback tick. All invalidates posted while an
-  // invalidate is pending will be posted as a single invalidate after the
-  // pending invalidate is done.
-  void PostInvalidateWithFallback();
-  void CancelFallbackTick();
   void UpdateCompositorIsActive();
   bool CompositeSW(SkCanvas* canvas);
   scoped_refptr<base::trace_event::ConvertableToTraceFormat>
   RootLayerStateAsValue(const gfx::Vector2dF& total_scroll_offset_dip,
                         const gfx::SizeF& scrollable_size_dip);
 
-  bool CompositeHw();
   void ReturnUnusedResource(scoped_ptr<ChildFrame> frame);
   void ReturnResourceFromParent();
 
@@ -142,11 +136,6 @@
   void PostFallbackTick();
   void FallbackTickFired();
 
-  // Force invoke the compositor to run produce a 1x1 software frame that is
-  // immediately discarded. This is a hack to force invoke parts of the
-  // compositor that are not directly exposed here.
-  void ForceFakeCompositeSW();
-
   gfx::Vector2d max_scroll_offset() const;
 
   void UpdateMemoryPolicy();
@@ -179,10 +168,6 @@
   gfx::Vector2d last_on_draw_scroll_offset_;
   gfx::Rect last_on_draw_global_visible_rect_;
 
-  base::CancelableClosure post_fallback_tick_;
-  base::CancelableClosure fallback_tick_fired_;
-  bool fallback_tick_pending_;
-
   gfx::Size size_;
 
   gfx::SizeF scrollable_size_dip_;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
index 2ae84a6..8af193f 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
@@ -9,13 +9,12 @@
 import android.graphics.Rect;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Base64;
-import android.view.View;
-import android.webkit.WebChromeClient;
 
 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
 
 import org.chromium.android_webview.AwContents;
 import org.chromium.android_webview.AwContents.VisualStateCallback;
+import org.chromium.android_webview.AwContentsClient;
 import org.chromium.android_webview.AwWebResourceResponse;
 import org.chromium.android_webview.test.util.CommonResources;
 import org.chromium.android_webview.test.util.GraphicsTestUtils;
@@ -32,6 +31,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
@@ -42,6 +42,8 @@
 public class VisualStateTest extends AwTestBase {
     private static final String WAIT_FOR_JS_TEST_URL =
             "file:///android_asset/visual_state_waits_for_js_test.html";
+    private static final String WAIT_FOR_JS_DETACHED_TEST_URL =
+            "file:///android_asset/visual_state_waits_for_js_detached_test.html";
     private static final String ON_PAGE_COMMIT_VISIBLE_TEST_URL =
             "file:///android_asset/visual_state_on_page_commit_visible_test.html";
     private static final String FULLSCREEN_TEST_URL =
@@ -403,77 +405,60 @@
         assertTrue(testFinishedSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
     }
 
-    @Feature({"AndroidWebView"})
-    @SmallTest
-    public void testVisualStateCallbackWhenContainerViewDetached()
-            throws Throwable {
-        final CountDownLatch readyToEnterFullscreenSignal = new CountDownLatch(1);
-        final CountDownLatch hasCustomViewSignal = new CountDownLatch(1);
-        final CountDownLatch testFinishedSignal = new CountDownLatch(1);
-
-        final AtomicReference<AwContents> awContentsRef = new AtomicReference<>();
-        final AtomicReference<View> customViewRef = new AtomicReference<>();
-
-        final TestAwContentsClient awContentsClient = new TestAwContentsClient() {
+    private AwTestContainerView createDetachedTestContainerViewOnMainSync(
+            final AwContentsClient awContentsClient) {
+        return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<AwTestContainerView>() {
             @Override
-            public void onPageFinished(String url) {
-                super.onPageFinished(url);
-                readyToEnterFullscreenSignal.countDown();
-            }
-
-            @Override
-            public void onShowCustomView(
-                    final View customView, WebChromeClient.CustomViewCallback callback) {
-                // Please note that we don't attach the custom view to the window here
-                // (awContentsClient is an instance of TestAwContentsClient, not
-                // FullScreenVideoTestAwContentsClient).
-                customView.setClipBounds(new Rect(0, 0, 100, 100));
-                customView.measure(100, 100);
-                customView.layout(0, 0, 100, 100);
-                customViewRef.set(customView);
-                hasCustomViewSignal.countDown();
-            }
-        };
-        final AwTestContainerView testView = createAwTestContainerViewOnMainSync(awContentsClient);
-        final AwContents awContents = testView.getAwContents();
-        awContentsRef.set(awContents);
-        final ContentViewCore contentViewCore = testView.getContentViewCore();
-        enableJavaScriptOnUiThread(awContents);
-        awContents.getSettings().setFullscreenSupported(true);
-
-        // JS will notify this observer once it has entered fullscreen.
-        final JavascriptEventObserver jsObserver = new JavascriptEventObserver();
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                jsObserver.register(contentViewCore, "jsObserver");
+            public AwTestContainerView call() {
+                AwTestContainerView detachedView =
+                        createDetachedAwTestContainerView(awContentsClient);
+                detachedView.setClipBounds(new Rect(0, 0, 100, 100));
+                detachedView.measure(100, 100);
+                detachedView.layout(0, 0, 100, 100);
+                return detachedView;
             }
         });
+    }
 
-        loadUrlSync(awContents, awContentsClient.getOnPageFinishedHelper(), FULLSCREEN_TEST_URL);
+    @Feature({"AndroidWebView"})
+    @SmallTest
+    public void testVisualStateCallbackWhenContainerViewDetached() throws Throwable {
+        final CountDownLatch testFinishedSignal = new CountDownLatch(1);
 
-        assertTrue(readyToEnterFullscreenSignal.await(
-                AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        DOMUtils.clickNode(VisualStateTest.this, contentViewCore, ENTER_FULLSCREEN_CONTROL_ID);
+        final TestAwContentsClient awContentsClient = new TestAwContentsClient();
+        final AwTestContainerView testView =
+                createDetachedTestContainerViewOnMainSync(awContentsClient);
+        final AwContents awContents = testView.getAwContents();
+        final ContentViewCore contentViewCore = testView.getContentViewCore();
 
-        assertTrue(hasCustomViewSignal.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertTrue(jsObserver.waitForEvent(WAIT_TIMEOUT_MS));
+        enableJavaScriptOnUiThread(awContents);
+
+        // JS will notify this observer once it has changed the background color of the page.
+        final Object pageChangeNotifier = new Object() {
+            public void onPageChanged() {
+                ThreadUtils.postOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        awContents.insertVisualStateCallback(20, new VisualStateCallback() {
+                            @Override
+                            public void onComplete(long id) {
+                                Bitmap redScreenshot =
+                                        GraphicsTestUtils.drawAwContents(awContents, 100, 100);
+                                assertEquals(Color.RED, redScreenshot.getPixel(50, 50));
+                                testFinishedSignal.countDown();
+                            }
+                        });
+                    }
+                });
+            }
+        };
 
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                awContents.insertVisualStateCallback(20, new VisualStateCallback() {
-                    @Override
-                    public void onComplete(long id) {
-                        assertFalse(customViewRef.get().isAttachedToWindow());
-                        // NOTE: We cannot use drawAwContents here because the web contents
-                        // are rendered into the custom view while in fullscreen.
-                        Bitmap redScreenshot = GraphicsTestUtils.drawView(
-                                customViewRef.get(), 100, 100);
-                        assertEquals(Color.RED, redScreenshot.getPixel(50, 50));
-                        testFinishedSignal.countDown();
-                    }
-                });
+                contentViewCore.addPossiblyUnsafeJavascriptInterface(
+                        pageChangeNotifier, "pageChangeNotifier", null);
+                awContents.loadUrl(WAIT_FOR_JS_DETACHED_TEST_URL);
             }
         });
 
diff --git a/android_webview/test/shell/assets/visual_state_waits_for_js_detached_test.html b/android_webview/test/shell/assets/visual_state_waits_for_js_detached_test.html
new file mode 100644
index 0000000..6bbf1020
--- /dev/null
+++ b/android_webview/test/shell/assets/visual_state_waits_for_js_detached_test.html
@@ -0,0 +1,19 @@
+<html>
+<head>
+  <script>
+    function updateColor() {
+      document.body.style.backgroundColor = "red";
+      pageChangeNotifier.onPageChanged();
+    }
+  </script>
+  <style>
+    body {
+      margin: 0px;
+      padding: 0px;
+      background-color: blue;
+    }
+  </style>
+</head>
+<body onload="javascript:updateColor()">
+</body>
+</html>
diff --git a/base/trace_event/memory_profiler_heap_dump_writer.cc b/base/trace_event/memory_profiler_heap_dump_writer.cc
index 81b1285..60e9929 100644
--- a/base/trace_event/memory_profiler_heap_dump_writer.cc
+++ b/base/trace_event/memory_profiler_heap_dump_writer.cc
@@ -117,7 +117,7 @@
     traced_value_->SetString("type", "");
   } else {
     // Format the type ID as a string.
-    SStringPrintf(&buffer_, "%i", type_id);
+    SStringPrintf(&buffer_, "%" PRIu16, type_id);
     traced_value_->SetString("type", buffer_);
   }
 }
diff --git a/blimp/engine/BUILD.gn b/blimp/engine/BUILD.gn
index 3522ae2c..edbcde1 100644
--- a/blimp/engine/BUILD.gn
+++ b/blimp/engine/BUILD.gn
@@ -57,11 +57,15 @@
   }
 
   group("blimp_engine") {
-    data_deps = [
+    deps = [
       ":blimp_engine_app",
       ":pak",
       "//sandbox/linux:chrome_sandbox",
     ]
+
+    # List dependencies as both deps and data_deps to ensure changes trigger a
+    # rebuild and "gn desc ... runtime_deps" correctly prints the data_deps.
+    data_deps = deps
   }
 
   # Builds and bundles the engine into a tarball that can be used to build a
diff --git a/blimp/engine/Dockerfile b/blimp/engine/Dockerfile
index 65e985a..21a4d224 100644
--- a/blimp/engine/Dockerfile
+++ b/blimp/engine/Dockerfile
@@ -17,11 +17,6 @@
 RUN mv /engine/chrome_sandbox /engine/chrome-sandbox
 RUN chown -R blimp_user /engine
 
-# TODO(sriramsr): Under Docker on GCE, the sandbox fails unless it's setuid
-# (crbug.com/551140).
-RUN chown root /engine/chrome-sandbox
-RUN chmod 4755 /engine/chrome-sandbox
-
 USER blimp_user
 WORKDIR "/engine"
 
diff --git a/blimp/engine/browser/blimp_browser_main_parts.cc b/blimp/engine/browser/blimp_browser_main_parts.cc
index 17f0625..232d8120 100644
--- a/blimp/engine/browser/blimp_browser_main_parts.cc
+++ b/blimp/engine/browser/blimp_browser_main_parts.cc
@@ -4,6 +4,7 @@
 
 #include "blimp/engine/browser/blimp_browser_main_parts.h"
 
+#include "blimp/common/proto/blimp_message.pb.h"
 #include "blimp/engine/browser/blimp_browser_context.h"
 #include "blimp/engine/browser/blimp_engine_session.h"
 #include "blimp/net/blimp_connection.h"
@@ -37,9 +38,18 @@
       new BlimpBrowserContext(false, net_log_.get()));
   engine_session_.reset(new BlimpEngineSession(browser_context.Pass()));
   engine_session_->Initialize();
-  // TODO(haibinlu): remove this after a real client connection can be attached.
-  scoped_ptr<BlimpConnection> clientConnection(new BlimpConnection);
-  engine_session_->AttachClientConnection(clientConnection.Pass());
+
+  // TODO(haibinlu): Create EngineConnectionManager to accept new connections.
+  // TODO(haibinlu): Remove these test messages and switch to using the
+  // MessageDispatcher for incoming messages.
+  BlimpMessage message;
+  message.set_type(BlimpMessage::CONTROL);
+  message.mutable_control()->set_type(ControlMessage::CREATE_TAB);
+  engine_session_->OnBlimpMessage(message);
+  message.mutable_control()->set_type(ControlMessage::LOAD_URL);
+  message.mutable_control()->mutable_load_url()->set_url(
+      "https://www.google.com/");
+  engine_session_->OnBlimpMessage(message);
 }
 
 void BlimpBrowserMainParts::PostMainMessageLoopRun() {
diff --git a/blimp/engine/browser/blimp_engine_session.cc b/blimp/engine/browser/blimp_engine_session.cc
index e4744d9..6ffd79da 100644
--- a/blimp/engine/browser/blimp_engine_session.cc
+++ b/blimp/engine/browser/blimp_engine_session.cc
@@ -86,23 +86,6 @@
   window_tree_host_->SetBounds(gfx::Rect(screen_->GetPrimaryDisplay().size()));
 }
 
-void BlimpEngineSession::AttachClientConnection(
-    scoped_ptr<BlimpConnection> client_connection) {
-  DCHECK(client_connection);
-  client_connection_ = client_connection.Pass();
-
-  // TODO(haibinlu): Remove this once we can use client connection to send in
-  // a navigation message.
-  BlimpMessage message;
-  message.set_type(BlimpMessage::CONTROL);
-  message.mutable_control()->set_type(ControlMessage::CREATE_TAB);
-  OnBlimpMessage(message);
-  message.mutable_control()->set_type(ControlMessage::LOAD_URL);
-  message.mutable_control()->mutable_load_url()->set_url(
-      "https://www.google.com/");
-  OnBlimpMessage(message);
-}
-
 void BlimpEngineSession::CreateWebContents(const int target_tab_id) {
   // TODO(haibinlu): Support more than one active WebContents (crbug/547231).
   DCHECK(!web_contents_);
diff --git a/blimp/engine/browser/blimp_engine_session.h b/blimp/engine/browser/blimp_engine_session.h
index 7a36b74..46b3039 100644
--- a/blimp/engine/browser/blimp_engine_session.h
+++ b/blimp/engine/browser/blimp_engine_session.h
@@ -52,7 +52,9 @@
 
   BlimpBrowserContext* browser_context() { return browser_context_.get(); }
 
-  void AttachClientConnection(scoped_ptr<BlimpConnection> client_connection);
+  // BlimpMessageReceiver implementation.
+  // TODO(haibinlu): Remove this in favor of the BlimpMessageDispatcher.
+  net::Error OnBlimpMessage(const BlimpMessage& message) override;
 
  private:
   // Creates a new WebContents, which will be indexed by |target_tab_id|.
@@ -61,9 +63,6 @@
   // Navigates the target tab to the |url|.
   void LoadUrl(const int target_tab_id, const GURL& url);
 
-  // BlimpMessageReceiver implementation.
-  net::Error OnBlimpMessage(const BlimpMessage& message) override;
-
   // content::WebContentsDelegate implementation.
   content::WebContents* OpenURLFromTab(
       content::WebContents* source,
diff --git a/blimp/net/BUILD.gn b/blimp/net/BUILD.gn
index 1b4da84..5adb729 100644
--- a/blimp/net/BUILD.gn
+++ b/blimp/net/BUILD.gn
@@ -13,10 +13,14 @@
     "blimp_transport.h",
     "common.cc",
     "common.h",
-    "packet_reader.cc",
     "packet_reader.h",
-    "packet_writer.cc",
     "packet_writer.h",
+    "stream_packet_reader.cc",
+    "stream_packet_reader.h",
+    "stream_packet_writer.cc",
+    "stream_packet_writer.h",
+    "stream_socket_connection.cc",
+    "stream_socket_connection.h",
     "tcp_client_transport.cc",
     "tcp_client_transport.h",
   ]
@@ -35,8 +39,8 @@
 
   sources = [
     "blimp_message_dispatcher_unittest.cc",
-    "packet_reader_unittest.cc",
-    "packet_writer_unittest.cc",
+    "stream_packet_reader_unittest.cc",
+    "stream_packet_writer_unittest.cc",
     "test_common.cc",
     "test_common.h",
   ]
diff --git a/blimp/net/blimp_connection.cc b/blimp/net/blimp_connection.cc
index cdc5bc8..5b9c917 100644
--- a/blimp/net/blimp_connection.cc
+++ b/blimp/net/blimp_connection.cc
@@ -4,9 +4,18 @@
 
 #include "blimp/net/blimp_connection.h"
 
+#include "base/macros.h"
+#include "blimp/net/packet_reader.h"
+#include "blimp/net/packet_writer.h"
+
 namespace blimp {
 
-BlimpConnection::BlimpConnection() {}
+BlimpConnection::BlimpConnection(scoped_ptr<PacketReader> reader,
+                                 scoped_ptr<PacketWriter> writer)
+    : reader_(reader.Pass()), writer_(writer.Pass()) {
+  DCHECK(reader_);
+  DCHECK(writer_);
+}
 
 BlimpConnection::~BlimpConnection() {}
 
diff --git a/blimp/net/blimp_connection.h b/blimp/net/blimp_connection.h
index 35336c4..5bd115d6 100644
--- a/blimp/net/blimp_connection.h
+++ b/blimp/net/blimp_connection.h
@@ -6,17 +6,25 @@
 #define BLIMP_NET_BLIMP_CONNECTION_H_
 
 #include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
 #include "blimp/net/blimp_net_export.h"
 
 namespace blimp {
 
+class PacketReader;
+class PacketWriter;
+
 class BLIMP_NET_EXPORT BlimpConnection {
  public:
-  BlimpConnection();
-  ~BlimpConnection();
+  virtual ~BlimpConnection();
+
+ protected:
+  BlimpConnection(scoped_ptr<PacketReader> reader,
+                  scoped_ptr<PacketWriter> writer);
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(BlimpConnection);
+  scoped_ptr<PacketReader> reader_;
+  scoped_ptr<PacketWriter> writer_;
 };
 
 }  // namespace blimp
diff --git a/blimp/net/blimp_transport.h b/blimp/net/blimp_transport.h
index 5ee9fff..56d5e34 100644
--- a/blimp/net/blimp_transport.h
+++ b/blimp/net/blimp_transport.h
@@ -7,10 +7,11 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "net/base/completion_callback.h"
-#include "net/socket/stream_socket.h"
 
 namespace blimp {
 
+class BlimpConnection;
+
 // An interface which encapsulates the transport-specific code for
 // establishing network connections between the client and engine.
 // Subclasses of BlimpTransport are responsible for defining their own
@@ -26,12 +27,12 @@
   // Returns net::ERR_IO_PENDING if the connection is being established
   // asynchronously. |callback| is later invoked with the connection outcome.
   //
-  // If the connection is successful, the connected socket can be taken by
+  // If the connection is successful, the BlimpConnection can be taken by
   // calling TakeConnectedSocket().
   virtual int Connect(const net::CompletionCallback& callback) = 0;
 
-  // Returns the connected socket following a successful Connect().
-  virtual scoped_ptr<net::StreamSocket> TakeConnectedSocket() = 0;
+  // Returns the connection object after a successful Connect().
+  virtual scoped_ptr<BlimpConnection> TakeConnection() = 0;
 };
 
 }  // namespace blimp
diff --git a/blimp/net/packet_reader.h b/blimp/net/packet_reader.h
index a9f948d..3c6abf8 100644
--- a/blimp/net/packet_reader.h
+++ b/blimp/net/packet_reader.h
@@ -5,81 +5,26 @@
 #ifndef BLIMP_NET_PACKET_READER_H_
 #define BLIMP_NET_PACKET_READER_H_
 
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
 #include "blimp/net/blimp_net_export.h"
 #include "net/base/completion_callback.h"
-#include "net/base/net_errors.h"
-
-namespace net {
-class GrowableIOBuffer;
-class StreamSocket;
-}  // namespace net
+#include "net/base/io_buffer.h"
 
 namespace blimp {
 
-// Reads opaque length-prefixed packets of bytes from a StreamSocket.
-// The header segment is 32-bit, encoded in network byte order.
-// The body segment length is specified in the header (capped at
-//     kMaxPacketPayloadSizeBytes).
+// Interface to describe a reader which can read variable-length data packets
+// from a connection.
 class BLIMP_NET_EXPORT PacketReader {
  public:
-  // |socket|: The socket to read packets from. The caller must ensure |socket|
-  // is valid while the reader is in-use (see ReadPacket below).
-  explicit PacketReader(net::StreamSocket* socket);
+  virtual ~PacketReader() {}
 
-  ~PacketReader();
-
-  // Reads a packet from the socket.
+  // Reads a packet from the connection.
   // Returns the size of the packet, in bytes, if the read operation executed
   // successfully.
   // Returns ERR_IO_PENDING if the operation will be executed asynchronously.
   //     |cb| is later invoked with the packet size or an error code.
   // All other return values indicate errors.
-  // |socket_| must be alive when this is called, but may be deleted while there
-  // is an outstanding read.
-  int ReadPacket(const scoped_refptr<net::GrowableIOBuffer>& buf,
-                 const net::CompletionCallback& cb);
-
- private:
-  enum class ReadState {
-    IDLE,
-    HEADER,
-    PAYLOAD,
-  };
-
-  friend std::ostream& operator<<(std::ostream& out, const ReadState state);
-
-  // State machine implementation.
-  // |result| - the result value of the most recent network operation.
-  // See comments for ReadPacket() for documentation on return values.
-  int DoReadLoop(int result);
-
-  // Reads the header and parses it when, done, to get the payload size.
-  int DoReadHeader(int result);
-
-  // Reads payload bytes until the payload is complete.
-  int DoReadPayload(int result);
-
-  // Processes an asynchronous header or payload read, and invokes |callback_|
-  // on packet read completion.
-  void OnReadComplete(int result);
-
-  ReadState read_state_;
-
-  net::StreamSocket* socket_;
-
-  // The size of the payload, in bytes.
-  size_t payload_size_;
-
-  scoped_refptr<net::GrowableIOBuffer> header_buffer_;
-  scoped_refptr<net::GrowableIOBuffer> payload_buffer_;
-  net::CompletionCallback callback_;
-
-  base::WeakPtrFactory<PacketReader> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PacketReader);
+  virtual int ReadPacket(const scoped_refptr<net::GrowableIOBuffer>& buf,
+                         const net::CompletionCallback& cb) = 0;
 };
 
 }  // namespace blimp
diff --git a/blimp/net/packet_writer.h b/blimp/net/packet_writer.h
index 79fc766497..1ac2126 100644
--- a/blimp/net/packet_writer.h
+++ b/blimp/net/packet_writer.h
@@ -8,72 +8,26 @@
 #include <string>
 
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/threading/thread_checker.h"
 #include "blimp/net/blimp_net_export.h"
 #include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 
-namespace net {
-class DrainableIOBuffer;
-class StreamSocket;
-}  // namespace net
-
 namespace blimp {
 
-// Writes opaque length-prefixed packets to a StreamSocket.
-// The header segment is 32-bit, encoded in network byte order.
-// The body segment length is specified in the header (should be capped at
-//     kMaxPacketPayloadSizeBytes).
+// Interface to describe a writer which can write variable-length data packets
+// to a connection.
 class BLIMP_NET_EXPORT PacketWriter {
  public:
-  // |socket|: The socket to write packets to. The caller must ensure |socket|
-  // is valid while the reader is in-use (see ReadPacket below).
-  explicit PacketWriter(net::StreamSocket* socket);
+  virtual ~PacketWriter() {}
 
-  ~PacketWriter();
-
-  // Writes a packet of at least one byte in size to |socket_|.
+  // Writes a packet of at least one byte in size to a connection.
   //
   // Returns net::OK or an error code if the operation executed successfully.
   // Returns ERR_IO_PENDING if the operation will be executed asynchronously.
   //     |cb| is later invoked with net::OK or an error code.
-  int WritePacket(scoped_refptr<net::DrainableIOBuffer> data,
-                  const net::CompletionCallback& callback);
-
- private:
-  enum class WriteState {
-    IDLE,
-    HEADER,
-    PAYLOAD,
-  };
-
-  friend std::ostream& operator<<(std::ostream& out, const WriteState state);
-
-  // State machine implementation.
-  // |result| - the result value of the most recent network operation.
-  // See comments for WritePacket() for documentation on return values.
-  int DoWriteLoop(int result);
-
-  int DoWriteHeader(int result);
-
-  int DoWritePayload(int result);
-
-  // Callback function to be invoked on asynchronous write completion.
-  // Invokes |callback_| on packet write completion or on error.
-  void OnWriteComplete(int result);
-
-  WriteState write_state_;
-
-  net::StreamSocket* socket_;
-
-  scoped_refptr<net::DrainableIOBuffer> payload_buffer_;
-  scoped_refptr<net::DrainableIOBuffer> header_buffer_;
-  net::CompletionCallback callback_;
-
-  base::WeakPtrFactory<PacketWriter> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PacketWriter);
+  virtual int WritePacket(scoped_refptr<net::DrainableIOBuffer> data,
+                          const net::CompletionCallback& callback) = 0;
 };
 
 }  // namespace blimp
diff --git a/blimp/net/packet_reader.cc b/blimp/net/stream_packet_reader.cc
similarity index 74%
rename from blimp/net/packet_reader.cc
rename to blimp/net/stream_packet_reader.cc
index 37cd30d..8da61302 100644
--- a/blimp/net/packet_reader.cc
+++ b/blimp/net/stream_packet_reader.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "blimp/net/packet_reader.h"
+#include "blimp/net/stream_packet_reader.h"
 
 #include <iostream>
 
@@ -18,32 +18,33 @@
 namespace blimp {
 
 std::ostream& operator<<(std::ostream& out,
-                         const PacketReader::ReadState state) {
+                         const StreamPacketReader::ReadState state) {
   switch (state) {
-    case PacketReader::ReadState::HEADER:
+    case StreamPacketReader::ReadState::HEADER:
       out << "HEADER";
       break;
-    case PacketReader::ReadState::PAYLOAD:
+    case StreamPacketReader::ReadState::PAYLOAD:
       out << "PAYLOAD";
       break;
-    case PacketReader::ReadState::IDLE:
+    case StreamPacketReader::ReadState::IDLE:
       out << "IDLE";
       break;
   }
   return out;
 }
 
-PacketReader::PacketReader(net::StreamSocket* socket)
+StreamPacketReader::StreamPacketReader(net::StreamSocket* socket)
     : read_state_(ReadState::IDLE), socket_(socket), weak_factory_(this) {
   DCHECK(socket_);
   header_buffer_ = new net::GrowableIOBuffer;
   header_buffer_->SetCapacity(kPacketHeaderSizeBytes);
 }
 
-PacketReader::~PacketReader() {}
+StreamPacketReader::~StreamPacketReader() {}
 
-int PacketReader::ReadPacket(const scoped_refptr<net::GrowableIOBuffer>& buf,
-                             const net::CompletionCallback& callback) {
+int StreamPacketReader::ReadPacket(
+    const scoped_refptr<net::GrowableIOBuffer>& buf,
+    const net::CompletionCallback& callback) {
   DCHECK_EQ(ReadState::IDLE, read_state_);
   DCHECK_GT(buf->capacity(), 0);
 
@@ -66,7 +67,7 @@
   return result;
 }
 
-int PacketReader::DoReadLoop(int result) {
+int StreamPacketReader::DoReadLoop(int result) {
   DCHECK_NE(net::ERR_IO_PENDING, result);
   DCHECK_GE(result, 0);
   DCHECK_NE(ReadState::IDLE, read_state_);
@@ -92,7 +93,7 @@
   return result;
 }
 
-int PacketReader::DoReadHeader(int result) {
+int StreamPacketReader::DoReadHeader(int result) {
   DCHECK_EQ(ReadState::HEADER, read_state_);
   DCHECK_GT(kPacketHeaderSizeBytes,
             static_cast<size_t>(header_buffer_->offset()));
@@ -101,9 +102,10 @@
   header_buffer_->set_offset(header_buffer_->offset() + result);
   if (static_cast<size_t>(header_buffer_->offset()) < kPacketHeaderSizeBytes) {
     // There is more header to read.
-    return socket_->Read(
-        header_buffer_.get(), kPacketHeaderSizeBytes - header_buffer_->offset(),
-        base::Bind(&PacketReader::OnReadComplete, weak_factory_.GetWeakPtr()));
+    return socket_->Read(header_buffer_.get(),
+                         kPacketHeaderSizeBytes - header_buffer_->offset(),
+                         base::Bind(&StreamPacketReader::OnReadComplete,
+                                    weak_factory_.GetWeakPtr()));
   }
 
   // Finished reading the header. Parse the size and prepare for payload read.
@@ -118,15 +120,16 @@
   return net::OK;
 }
 
-int PacketReader::DoReadPayload(int result) {
+int StreamPacketReader::DoReadPayload(int result) {
   DCHECK_EQ(ReadState::PAYLOAD, read_state_);
   DCHECK_GE(result, 0);
 
   payload_buffer_->set_offset(payload_buffer_->offset() + result);
   if (static_cast<size_t>(payload_buffer_->offset()) < payload_size_) {
-    return socket_->Read(
-        payload_buffer_.get(), payload_size_ - payload_buffer_->offset(),
-        base::Bind(&PacketReader::OnReadComplete, weak_factory_.GetWeakPtr()));
+    return socket_->Read(payload_buffer_.get(),
+                         payload_size_ - payload_buffer_->offset(),
+                         base::Bind(&StreamPacketReader::OnReadComplete,
+                                    weak_factory_.GetWeakPtr()));
   }
 
   // Finished reading the payload.
@@ -134,7 +137,7 @@
   return payload_size_;
 }
 
-void PacketReader::OnReadComplete(int result) {
+void StreamPacketReader::OnReadComplete(int result) {
   DCHECK_NE(net::ERR_IO_PENDING, result);
 
   // If the read was succesful, then process the result.
diff --git a/blimp/net/stream_packet_reader.h b/blimp/net/stream_packet_reader.h
new file mode 100644
index 0000000..4468638d
--- /dev/null
+++ b/blimp/net/stream_packet_reader.h
@@ -0,0 +1,81 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BLIMP_NET_STREAM_PACKET_READER_H_
+#define BLIMP_NET_STREAM_PACKET_READER_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "blimp/net/blimp_net_export.h"
+#include "blimp/net/packet_reader.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_errors.h"
+
+namespace net {
+class GrowableIOBuffer;
+class StreamSocket;
+}  // namespace net
+
+namespace blimp {
+
+// Reads opaque length-prefixed packets of bytes from a StreamSocket.
+// The header segment is 32-bit, encoded in network byte order.
+// The body segment length is specified in the header (capped at
+//     kMaxPacketPayloadSizeBytes).
+class BLIMP_NET_EXPORT StreamPacketReader : public PacketReader {
+ public:
+  // |socket|: The socket to read packets from. The caller must ensure |socket|
+  // is valid while the reader is in-use (see ReadPacket below).
+  explicit StreamPacketReader(net::StreamSocket* socket);
+
+  ~StreamPacketReader() override;
+
+  // PacketReader implementation.
+  int ReadPacket(const scoped_refptr<net::GrowableIOBuffer>& buf,
+                 const net::CompletionCallback& cb) override;
+
+ private:
+  enum class ReadState {
+    IDLE,
+    HEADER,
+    PAYLOAD,
+  };
+
+  friend std::ostream& operator<<(std::ostream& out, const ReadState state);
+
+  // State machine implementation.
+  // |result| - the result value of the most recent network operation.
+  // See comments for ReadPacket() for documentation on return values.
+  int DoReadLoop(int result);
+
+  // Reads the header and parses it when, done, to get the payload size.
+  int DoReadHeader(int result);
+
+  // Reads payload bytes until the payload is complete.
+  int DoReadPayload(int result);
+
+  // Processes an asynchronous header or payload read, and invokes |callback_|
+  // on packet read completion.
+  void OnReadComplete(int result);
+
+  ReadState read_state_;
+
+  net::StreamSocket* socket_;
+
+  // The size of the payload, in bytes.
+  size_t payload_size_;
+
+  scoped_refptr<net::GrowableIOBuffer> header_buffer_;
+  scoped_refptr<net::GrowableIOBuffer> payload_buffer_;
+  net::CompletionCallback callback_;
+
+  base::WeakPtrFactory<StreamPacketReader> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(StreamPacketReader);
+};
+
+}  // namespace blimp
+
+#endif  // BLIMP_NET_STREAM_PACKET_READER_H_
diff --git a/blimp/net/packet_reader_unittest.cc b/blimp/net/stream_packet_reader_unittest.cc
similarity index 90%
rename from blimp/net/packet_reader_unittest.cc
rename to blimp/net/stream_packet_reader_unittest.cc
index 5981d58..61419cf 100644
--- a/blimp/net/packet_reader_unittest.cc
+++ b/blimp/net/stream_packet_reader_unittest.cc
@@ -7,7 +7,7 @@
 
 #include "base/sys_byteorder.h"
 #include "blimp/net/common.h"
-#include "blimp/net/packet_reader.h"
+#include "blimp/net/stream_packet_reader.h"
 #include "blimp/net/test_common.h"
 #include "net/base/completion_callback.h"
 #include "net/base/io_buffer.h"
@@ -30,16 +30,16 @@
 
 const size_t kTestMaxBufferSize = 1 << 16;  // 64KB
 
-class PacketReaderTest : public testing::Test {
+class StreamPacketReaderTest : public testing::Test {
  public:
-  PacketReaderTest()
+  StreamPacketReaderTest()
       : buffer_(new net::GrowableIOBuffer),
         test_msg_("U WOT M8"),
         data_reader_(&socket_) {
     buffer_->SetCapacity(kTestMaxBufferSize);
   }
 
-  ~PacketReaderTest() override {}
+  ~StreamPacketReaderTest() override {}
 
   int ReadPacket() {
     return data_reader_.ReadPacket(buffer_, callback_.callback());
@@ -51,11 +51,11 @@
   net::TestCompletionCallback callback_;
   testing::StrictMock<MockStreamSocket> socket_;
   testing::InSequence sequence_;
-  PacketReader data_reader_;
+  StreamPacketReader data_reader_;
 };
 
 // Successful read with 1 async header read and 1 async payload read.
-TEST_F(PacketReaderTest, ReadAsyncHeaderAsyncPayload) {
+TEST_F(StreamPacketReaderTest, ReadAsyncHeaderAsyncPayload) {
   net::CompletionCallback socket_cb;
 
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
@@ -75,7 +75,7 @@
 }
 
 // Successful read with 1 async header read and 1 sync payload read.
-TEST_F(PacketReaderTest, ReadAsyncHeaderSyncPayload) {
+TEST_F(StreamPacketReaderTest, ReadAsyncHeaderSyncPayload) {
   net::CompletionCallback socket_cb;
 
   // Asynchronous payload read expectation.
@@ -100,7 +100,7 @@
 }
 
 // Successful read with 1 sync header read and 1 async payload read.
-TEST_F(PacketReaderTest, ReadSyncHeaderAsyncPayload) {
+TEST_F(StreamPacketReaderTest, ReadSyncHeaderAsyncPayload) {
   net::CompletionCallback socket_cb;
 
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
@@ -120,7 +120,7 @@
 }
 
 // Successful read with 1 sync header read and 1 sync payload read.
-TEST_F(PacketReaderTest, ReadSyncHeaderSyncPayload) {
+TEST_F(StreamPacketReaderTest, ReadSyncHeaderSyncPayload) {
   net::CompletionCallback socket_cb;
 
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
@@ -140,7 +140,7 @@
 
 // Successful read of 2 messages, header and payload reads all completing
 // synchronously with no partial results.
-TEST_F(PacketReaderTest, ReadMultipleMessagesSync) {
+TEST_F(StreamPacketReaderTest, ReadMultipleMessagesSync) {
   net::CompletionCallback socket_cb;
   std::string test_msg2 = test_msg_ + "SlightlyLongerString";
 
@@ -181,7 +181,7 @@
 
 // Successful read of 2 messages, header and payload reads all completing
 // asynchronously with no partial results.
-TEST_F(PacketReaderTest, ReadMultipleMessagesAsync) {
+TEST_F(StreamPacketReaderTest, ReadMultipleMessagesAsync) {
   net::TestCompletionCallback read_cb1;
   net::TestCompletionCallback read_cb2;
   net::CompletionCallback socket_cb;
@@ -233,7 +233,7 @@
 // Verify that partial header reads are supported.
 // Read #0: 1 header byte is read.
 // Read #1: Remainder of header bytes read.
-TEST_F(PacketReaderTest, PartialHeaderReadAsync) {
+TEST_F(StreamPacketReaderTest, PartialHeaderReadAsync) {
   net::CompletionCallback cb;
   std::string header = EncodeHeader(test_msg_.size());
 
@@ -259,7 +259,7 @@
 // Read #0: Header is fully read synchronously.
 // Read #1: First payload byte is read. (Um, it's an acoustic cup modem.)
 // Read #2: Remainder of payload bytes are read.
-TEST_F(PacketReaderTest, PartialPayloadReadAsync) {
+TEST_F(StreamPacketReaderTest, PartialPayloadReadAsync) {
   net::CompletionCallback cb;
 
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
@@ -283,7 +283,7 @@
 }
 
 // Verify that synchronous header read errors are reported correctly.
-TEST_F(PacketReaderTest, ReadHeaderErrorSync) {
+TEST_F(StreamPacketReaderTest, ReadHeaderErrorSync) {
   net::CompletionCallback cb;
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
       .WillOnce(Return(net::ERR_FAILED));
@@ -291,7 +291,7 @@
 }
 
 // Verify that synchronous payload read errors are reported correctly.
-TEST_F(PacketReaderTest, ReadPayloadErrorSync) {
+TEST_F(StreamPacketReaderTest, ReadPayloadErrorSync) {
   net::CompletionCallback cb;
 
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
@@ -304,7 +304,7 @@
 }
 
 // Verify that async header read errors are reported correctly.
-TEST_F(PacketReaderTest, ReadHeaderErrorAsync) {
+TEST_F(StreamPacketReaderTest, ReadHeaderErrorAsync) {
   net::CompletionCallback cb;
   net::TestCompletionCallback test_cb;
 
@@ -318,7 +318,7 @@
 }
 
 // Verify that asynchronous paylod read errors are reported correctly.
-TEST_F(PacketReaderTest, ReadPayloadErrorAsync) {
+TEST_F(StreamPacketReaderTest, ReadPayloadErrorAsync) {
   net::CompletionCallback cb;
 
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
@@ -332,12 +332,12 @@
   EXPECT_EQ(net::ERR_FAILED, callback_.WaitForResult());
 }
 
-// Verify that async header read completions don't break us if the PacketReader
-// object was destroyed.
-TEST_F(PacketReaderTest, ReaderDeletedDuringAsyncHeaderRead) {
+// Verify that async header read completions don't break us if the
+// StreamPacketReader object was destroyed.
+TEST_F(StreamPacketReaderTest, ReaderDeletedDuringAsyncHeaderRead) {
   net::CompletionCallback cb;
   net::TestCompletionCallback test_cb;
-  scoped_ptr<PacketReader> reader(new PacketReader(&socket_));
+  scoped_ptr<StreamPacketReader> reader(new StreamPacketReader(&socket_));
 
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
       .WillOnce(DoAll(FillBufferFromString<0>(EncodeHeader(test_msg_.size())),
@@ -349,11 +349,11 @@
   cb.Run(kPacketHeaderSizeBytes);  // Complete the socket operation.
 }
 
-// Verify that async payload read completions don't break us if the PacketReader
-// object was destroyed.
-TEST_F(PacketReaderTest, ReaderDeletedDuringAsyncPayloadRead) {
+// Verify that async payload read completions don't break us if the
+// StreamPacketReader object was destroyed.
+TEST_F(StreamPacketReaderTest, ReaderDeletedDuringAsyncPayloadRead) {
   net::CompletionCallback cb;
-  scoped_ptr<PacketReader> reader(new PacketReader(&socket_));
+  scoped_ptr<StreamPacketReader> reader(new StreamPacketReader(&socket_));
 
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
       .WillOnce(DoAll(FillBufferFromString<0>(EncodeHeader(test_msg_.size())),
@@ -368,7 +368,7 @@
 }
 
 // Verify that zero-length payload is reported as an erroneous input.
-TEST_F(PacketReaderTest, ReadWhatIsThisAPacketForAnts) {
+TEST_F(StreamPacketReaderTest, ReadWhatIsThisAPacketForAnts) {
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
       .WillOnce(DoAll(FillBufferFromString<0>(EncodeHeader(0)),
                       Return(kPacketHeaderSizeBytes)))
@@ -378,7 +378,7 @@
 }
 
 // Verify that an illegally large payloads is reported as an erroneous inputs.
-TEST_F(PacketReaderTest, ReadErrorIllegallyLargePayload) {
+TEST_F(StreamPacketReaderTest, ReadErrorIllegallyLargePayload) {
   EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _))
       .WillOnce(
           DoAll(FillBufferFromString<0>(EncodeHeader(kTestMaxBufferSize + 1)),
diff --git a/blimp/net/packet_writer.cc b/blimp/net/stream_packet_writer.cc
similarity index 72%
rename from blimp/net/packet_writer.cc
rename to blimp/net/stream_packet_writer.cc
index 81a6d90..221cdd17 100644
--- a/blimp/net/packet_writer.cc
+++ b/blimp/net/stream_packet_writer.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "blimp/net/packet_writer.h"
+#include "blimp/net/stream_packet_writer.h"
 
 #include <iostream>
 
@@ -20,22 +20,22 @@
 namespace blimp {
 
 std::ostream& operator<<(std::ostream& out,
-                         const PacketWriter::WriteState state) {
+                         const StreamPacketWriter::WriteState state) {
   switch (state) {
-    case PacketWriter::WriteState::IDLE:
+    case StreamPacketWriter::WriteState::IDLE:
       out << "IDLE";
       break;
-    case PacketWriter::WriteState::HEADER:
+    case StreamPacketWriter::WriteState::HEADER:
       out << "HEADER";
       break;
-    case PacketWriter::WriteState::PAYLOAD:
+    case StreamPacketWriter::WriteState::PAYLOAD:
       out << "PAYLOAD";
       break;
   }
   return out;
 }
 
-PacketWriter::PacketWriter(net::StreamSocket* socket)
+StreamPacketWriter::StreamPacketWriter(net::StreamSocket* socket)
     : write_state_(WriteState::IDLE),
       socket_(socket),
       header_buffer_(
@@ -45,10 +45,10 @@
   DCHECK(socket_);
 }
 
-PacketWriter::~PacketWriter() {}
+StreamPacketWriter::~StreamPacketWriter() {}
 
-int PacketWriter::WritePacket(scoped_refptr<net::DrainableIOBuffer> data,
-                              const net::CompletionCallback& callback) {
+int StreamPacketWriter::WritePacket(scoped_refptr<net::DrainableIOBuffer> data,
+                                    const net::CompletionCallback& callback) {
   DCHECK_EQ(WriteState::IDLE, write_state_);
   DCHECK(data);
   if (data->BytesRemaining() == 0) {
@@ -77,7 +77,7 @@
   return result;
 }
 
-int PacketWriter::DoWriteLoop(int result) {
+int StreamPacketWriter::DoWriteLoop(int result) {
   DCHECK_NE(net::ERR_IO_PENDING, result);
   DCHECK_GE(result, 0);
   DCHECK_NE(WriteState::IDLE, write_state_);
@@ -103,37 +103,39 @@
   return result;
 }
 
-int PacketWriter::DoWriteHeader(int result) {
+int StreamPacketWriter::DoWriteHeader(int result) {
   DCHECK_EQ(WriteState::HEADER, write_state_);
   DCHECK_GE(result, 0);
 
   header_buffer_->DidConsume(result);
   if (header_buffer_->BytesRemaining() > 0) {
-    return socket_->Write(
-        header_buffer_.get(), header_buffer_->BytesRemaining(),
-        base::Bind(&PacketWriter::OnWriteComplete, weak_factory_.GetWeakPtr()));
+    return socket_->Write(header_buffer_.get(),
+                          header_buffer_->BytesRemaining(),
+                          base::Bind(&StreamPacketWriter::OnWriteComplete,
+                                     weak_factory_.GetWeakPtr()));
   }
 
   write_state_ = WriteState::PAYLOAD;
   return net::OK;
 }
 
-int PacketWriter::DoWritePayload(int result) {
+int StreamPacketWriter::DoWritePayload(int result) {
   DCHECK_EQ(WriteState::PAYLOAD, write_state_);
   DCHECK_GE(result, 0);
 
   payload_buffer_->DidConsume(result);
   if (payload_buffer_->BytesRemaining() > 0) {
-    return socket_->Write(
-        payload_buffer_.get(), payload_buffer_->BytesRemaining(),
-        base::Bind(&PacketWriter::OnWriteComplete, weak_factory_.GetWeakPtr()));
+    return socket_->Write(payload_buffer_.get(),
+                          payload_buffer_->BytesRemaining(),
+                          base::Bind(&StreamPacketWriter::OnWriteComplete,
+                                     weak_factory_.GetWeakPtr()));
   }
 
   write_state_ = WriteState::IDLE;
   return net::OK;
 }
 
-void PacketWriter::OnWriteComplete(int result) {
+void StreamPacketWriter::OnWriteComplete(int result) {
   DCHECK_NE(net::ERR_IO_PENDING, result);
 
   // If the write was succesful, then process the result.
diff --git a/blimp/net/stream_packet_writer.h b/blimp/net/stream_packet_writer.h
new file mode 100644
index 0000000..c618eba
--- /dev/null
+++ b/blimp/net/stream_packet_writer.h
@@ -0,0 +1,78 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BLIMP_NET_STREAM_PACKET_WRITER_H_
+#define BLIMP_NET_STREAM_PACKET_WRITER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/thread_checker.h"
+#include "blimp/net/blimp_net_export.h"
+#include "blimp/net/packet_writer.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_errors.h"
+
+namespace net {
+class DrainableIOBuffer;
+class StreamSocket;
+}  // namespace net
+
+namespace blimp {
+
+// Writes opaque length-prefixed packets to a StreamSocket.
+// The header segment is 32-bit, encoded in network byte order.
+// The body segment length is specified in the header (should be capped at
+//     kMaxPacketPayloadSizeBytes).
+class BLIMP_NET_EXPORT StreamPacketWriter : public PacketWriter {
+ public:
+  // |socket|: The socket to write packets to. The caller must ensure |socket|
+  // is valid while the reader is in-use (see ReadPacket below).
+  explicit StreamPacketWriter(net::StreamSocket* socket);
+
+  ~StreamPacketWriter() override;
+
+  // PacketWriter implementation.
+  int WritePacket(scoped_refptr<net::DrainableIOBuffer> data,
+                  const net::CompletionCallback& callback) override;
+
+ private:
+  enum class WriteState {
+    IDLE,
+    HEADER,
+    PAYLOAD,
+  };
+
+  friend std::ostream& operator<<(std::ostream& out, const WriteState state);
+
+  // State machine implementation.
+  // |result| - the result value of the most recent network operation.
+  // See comments for WritePacket() for documentation on return values.
+  int DoWriteLoop(int result);
+
+  int DoWriteHeader(int result);
+
+  int DoWritePayload(int result);
+
+  // Callback function to be invoked on asynchronous write completion.
+  // Invokes |callback_| on packet write completion or on error.
+  void OnWriteComplete(int result);
+
+  WriteState write_state_;
+
+  net::StreamSocket* socket_;
+
+  scoped_refptr<net::DrainableIOBuffer> payload_buffer_;
+  scoped_refptr<net::DrainableIOBuffer> header_buffer_;
+  net::CompletionCallback callback_;
+
+  base::WeakPtrFactory<StreamPacketWriter> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(StreamPacketWriter);
+};
+
+}  // namespace blimp
+
+#endif  // BLIMP_NET_STREAM_PACKET_WRITER_H_
diff --git a/blimp/net/packet_writer_unittest.cc b/blimp/net/stream_packet_writer_unittest.cc
similarity index 90%
rename from blimp/net/packet_writer_unittest.cc
rename to blimp/net/stream_packet_writer_unittest.cc
index 2554b47..c8014f94 100644
--- a/blimp/net/packet_writer_unittest.cc
+++ b/blimp/net/stream_packet_writer_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "blimp/net/common.h"
-#include "blimp/net/packet_writer.h"
+#include "blimp/net/stream_packet_writer.h"
 #include "blimp/net/test_common.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
@@ -27,31 +27,31 @@
 namespace blimp {
 namespace {
 
-class PacketWriterTest : public testing::Test {
+class StreamPacketWriterTest : public testing::Test {
  public:
-  PacketWriterTest()
+  StreamPacketWriterTest()
       : test_data_(
             new net::DrainableIOBuffer(new net::StringIOBuffer(test_data_str_),
                                        test_data_str_.size())),
         message_writer_(&socket_) {}
 
-  ~PacketWriterTest() override {}
+  ~StreamPacketWriterTest() override {}
 
  protected:
   const std::string test_data_str_ = "U WOT M8";
   scoped_refptr<net::DrainableIOBuffer> test_data_;
 
   MockStreamSocket socket_;
-  PacketWriter message_writer_;
+  StreamPacketWriter message_writer_;
   base::MessageLoop message_loop_;
   testing::InSequence mock_sequence_;
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(PacketWriterTest);
+  DISALLOW_COPY_AND_ASSIGN(StreamPacketWriterTest);
 };
 
 // Successful write with 1 async header write and 1 async payload write.
-TEST_F(PacketWriterTest, TestWriteAsync) {
+TEST_F(StreamPacketWriterTest, TestWriteAsync) {
   net::TestCompletionCallback writer_cb;
   net::CompletionCallback header_cb;
   net::CompletionCallback payload_cb;
@@ -76,7 +76,7 @@
 }
 
 // Successful write with 2 async header writes and 2 async payload writes.
-TEST_F(PacketWriterTest, TestPartialWriteAsync) {
+TEST_F(StreamPacketWriterTest, TestPartialWriteAsync) {
   net::TestCompletionCallback writer_cb;
   net::CompletionCallback header_cb;
   net::CompletionCallback payload_cb;
@@ -115,7 +115,7 @@
 }
 
 // Async socket error while writing data.
-TEST_F(PacketWriterTest, TestWriteErrorAsync) {
+TEST_F(StreamPacketWriterTest, TestWriteErrorAsync) {
   net::TestCompletionCallback writer_cb;
   net::CompletionCallback header_cb;
   net::CompletionCallback payload_cb;
@@ -136,7 +136,7 @@
 }
 
 // Successful write with 1 sync header write and 1 sync payload write.
-TEST_F(PacketWriterTest, TestWriteSync) {
+TEST_F(StreamPacketWriterTest, TestWriteSync) {
   net::TestCompletionCallback writer_cb;
   EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())),
                              kPacketHeaderSizeBytes, _))
@@ -150,7 +150,7 @@
 }
 
 // Successful write with 2 sync header writes and 2 sync payload writes.
-TEST_F(PacketWriterTest, TestPartialWriteSync) {
+TEST_F(StreamPacketWriterTest, TestPartialWriteSync) {
   net::TestCompletionCallback writer_cb;
 
   std::string header = EncodeHeader(test_data_str_.size());
@@ -173,7 +173,7 @@
 }
 
 // Verify that zero-length packets are rejected.
-TEST_F(PacketWriterTest, TestZeroLengthPacketsRejected) {
+TEST_F(StreamPacketWriterTest, TestZeroLengthPacketsRejected) {
   net::TestCompletionCallback writer_cb;
 
   EXPECT_EQ(net::ERR_INVALID_ARGUMENT,
@@ -185,7 +185,7 @@
 }
 
 // Sync socket error while writing header data.
-TEST_F(PacketWriterTest, TestWriteHeaderErrorSync) {
+TEST_F(StreamPacketWriterTest, TestWriteHeaderErrorSync) {
   net::TestCompletionCallback writer_cb;
 
   EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())),
@@ -201,7 +201,7 @@
 }
 
 // Sync socket error while writing payload data.
-TEST_F(PacketWriterTest, TestWritePayloadErrorSync) {
+TEST_F(StreamPacketWriterTest, TestWritePayloadErrorSync) {
   net::TestCompletionCallback writer_cb;
 
   EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())),
@@ -218,11 +218,11 @@
 
 // Verify that asynchronous header write completions don't cause a
 // use-after-free error if the writer object is deleted.
-TEST_F(PacketWriterTest, DeletedDuringHeaderWrite) {
+TEST_F(StreamPacketWriterTest, DeletedDuringHeaderWrite) {
   net::TestCompletionCallback writer_cb;
   net::CompletionCallback header_cb;
   net::CompletionCallback payload_cb;
-  scoped_ptr<PacketWriter> writer(new PacketWriter(&socket_));
+  scoped_ptr<StreamPacketWriter> writer(new StreamPacketWriter(&socket_));
 
   // Write header.
   EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())),
@@ -239,11 +239,11 @@
 
 // Verify that asynchronous payload write completions don't cause a
 // use-after-free error if the writer object is deleted.
-TEST_F(PacketWriterTest, DeletedDuringPayloadWrite) {
+TEST_F(StreamPacketWriterTest, DeletedDuringPayloadWrite) {
   net::TestCompletionCallback writer_cb;
   net::CompletionCallback header_cb;
   net::CompletionCallback payload_cb;
-  scoped_ptr<PacketWriter> writer(new PacketWriter(&socket_));
+  scoped_ptr<StreamPacketWriter> writer(new StreamPacketWriter(&socket_));
 
   EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())),
                              kPacketHeaderSizeBytes, _))
diff --git a/blimp/net/stream_socket_connection.cc b/blimp/net/stream_socket_connection.cc
new file mode 100644
index 0000000..ec06206
--- /dev/null
+++ b/blimp/net/stream_socket_connection.cc
@@ -0,0 +1,22 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "blimp/net/stream_socket_connection.h"
+
+#include "blimp/net/stream_packet_reader.h"
+#include "blimp/net/stream_packet_writer.h"
+
+namespace blimp {
+
+StreamSocketConnection::StreamSocketConnection(
+    scoped_ptr<net::StreamSocket> socket)
+    : BlimpConnection(make_scoped_ptr(new StreamPacketReader(socket.get())),
+                      make_scoped_ptr(new StreamPacketWriter(socket.get()))),
+      socket_(socket.Pass()) {
+  DCHECK(socket_);
+}
+
+StreamSocketConnection::~StreamSocketConnection() {}
+
+}  // namespace blimp
diff --git a/blimp/net/stream_socket_connection.h b/blimp/net/stream_socket_connection.h
new file mode 100644
index 0000000..9739a09
--- /dev/null
+++ b/blimp/net/stream_socket_connection.h
@@ -0,0 +1,31 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BLIMP_NET_STREAM_SOCKET_CONNECTION_H_
+#define BLIMP_NET_STREAM_SOCKET_CONNECTION_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "blimp/net/blimp_connection.h"
+#include "net/socket/stream_socket.h"
+
+namespace net {
+class StreamSocket;
+}  // namespace net
+
+namespace blimp {
+
+// BlimpConnection specialization for StreamSocket-based connections.
+class StreamSocketConnection : public BlimpConnection {
+ public:
+  explicit StreamSocketConnection(scoped_ptr<net::StreamSocket> socket);
+
+  ~StreamSocketConnection() override;
+
+ private:
+  scoped_ptr<net::StreamSocket> socket_;
+};
+
+}  // namespace blimp
+
+#endif  // BLIMP_NET_STREAM_SOCKET_CONNECTION_H_
diff --git a/blimp/net/tcp_client_transport.cc b/blimp/net/tcp_client_transport.cc
index 3d52aa4..8ac24a8 100644
--- a/blimp/net/tcp_client_transport.cc
+++ b/blimp/net/tcp_client_transport.cc
@@ -7,6 +7,7 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/memory/scoped_ptr.h"
+#include "blimp/net/stream_socket_connection.h"
 #include "net/socket/stream_socket.h"
 #include "net/socket/tcp_client_socket.h"
 
@@ -19,34 +20,36 @@
 TCPClientTransport::~TCPClientTransport() {}
 
 int TCPClientTransport::Connect(const net::CompletionCallback& callback) {
-  DCHECK(!socket_);
+  DCHECK(!connection_);
   DCHECK(!callback.is_null());
 
-  socket_.reset(
+  scoped_ptr<net::StreamSocket> socket;
+  socket.reset(
       new net::TCPClientSocket(addresses_, net_log_, net::NetLog::Source()));
   net::CompletionCallback completion_callback = base::Bind(
       &TCPClientTransport::OnTCPConnectComplete, base::Unretained(this));
 
-  int result = socket_->Connect(completion_callback);
+  int result = socket->Connect(completion_callback);
+  connection_.reset(new StreamSocketConnection(socket.Pass()));
   if (result == net::ERR_IO_PENDING) {
     connect_callback_ = callback;
   } else if (result != net::OK) {
-    socket_ = nullptr;
+    connection_ = nullptr;
   }
 
   return result;
 }
 
-scoped_ptr<net::StreamSocket> TCPClientTransport::TakeConnectedSocket() {
-  DCHECK(socket_);
+scoped_ptr<BlimpConnection> TCPClientTransport::TakeConnection() {
+  DCHECK(connection_);
   DCHECK(connect_callback_.is_null());
-  return socket_.Pass();
+  return connection_.Pass();
 }
 
 void TCPClientTransport::OnTCPConnectComplete(int result) {
-  DCHECK(socket_);
+  DCHECK(connection_);
   if (result != net::OK) {
-    socket_ = nullptr;
+    connection_ = nullptr;
   }
   base::ResetAndReturn(&connect_callback_).Run(result);
 }
diff --git a/blimp/net/tcp_client_transport.h b/blimp/net/tcp_client_transport.h
index ac383d50..77ca287 100644
--- a/blimp/net/tcp_client_transport.h
+++ b/blimp/net/tcp_client_transport.h
@@ -14,11 +14,12 @@
 
 namespace net {
 class NetLog;
-class StreamSocket;
 }  // namespace net
 
 namespace blimp {
 
+class BlimpConnection;
+
 // BlimpTransport which creates a TCP connection to one of the specified
 // |addresses| on each call to Connect().
 class TCPClientTransport : public BlimpTransport {
@@ -28,14 +29,14 @@
 
   // BlimpTransport implementation.
   int Connect(const net::CompletionCallback& callback) override;
-  scoped_ptr<net::StreamSocket> TakeConnectedSocket() override;
+  scoped_ptr<BlimpConnection> TakeConnection() override;
 
  private:
   void OnTCPConnectComplete(int result);
 
   net::AddressList addresses_;
   net::NetLog* net_log_;
-  scoped_ptr<net::StreamSocket> socket_;
+  scoped_ptr<BlimpConnection> connection_;
   net::CompletionCallback connect_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(TCPClientTransport);
diff --git a/build/android/gyp/create_java_binary_script.py b/build/android/gyp/create_java_binary_script.py
index 324361d4..721e96f 100755
--- a/build/android/gyp/create_java_binary_script.py
+++ b/build/android/gyp/create_java_binary_script.py
@@ -69,6 +69,7 @@
     bootclasspath += build_utils.ParseGypList(bootcp_arg)
 
   run_dir = os.path.dirname(options.output)
+  bootclasspath = [os.path.relpath(p, run_dir) for p in bootclasspath]
   classpath = [os.path.relpath(p, run_dir) for p in classpath]
 
   with open(options.output, 'w') as script:
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 57b3a1b..0866aa4d 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -590,6 +590,7 @@
 #   rezip_apk: Whether to add crazy-linker alignment.
 template("finalize_apk") {
   action(target_name) {
+    deps = []
     script = "//build/android/gyp/finalize_apk.py"
     depfile = "$target_gen_dir/$target_name.d"
     forward_variables_from(invoker,
@@ -628,8 +629,8 @@
       invoker.keystore_password,
     ]
     if (defined(invoker.rezip_apk) && invoker.rezip_apk) {
+      deps += [ "//build/android/rezip" ]
       _rezip_jar_path = "$root_build_dir/lib.java/rezip_apk.jar"
-      inputs += [ _rezip_jar_path ]
       args += [
         "--load-library-from-zip=1",
         "--rezip-apk-jar-path",
diff --git a/build/config/ui.gni b/build/config/ui.gni
index f7070bbf..e534366b 100644
--- a/build/config/ui.gni
+++ b/build/config/ui.gni
@@ -42,6 +42,9 @@
 
   # Optional system libraries.
   use_xkbcommon = false
+
+  # Whether we should use glib, a low level C utility library.
+  use_glib = is_linux
 }
 
 # Additional dependent variables -----------------------------------------------
@@ -57,10 +60,12 @@
 # Indicates if the UI toolkit depends on X11.
 use_x11 = is_linux && !use_ozone
 
-# Whether we should use glib, a low level C utility library.
-use_glib = is_linux && !use_ozone
+# Turn off glib if Ozone is enabled.
+if (use_ozone) {
+  use_glib = false
+}
 
-if (is_linux && use_glib) {
+if (is_linux && !use_ozone) {
   use_cairo = true
   use_pango = true
 } else {
diff --git a/build/filename_rules.gypi b/build/filename_rules.gypi
index f67287fa..3766273 100644
--- a/build/filename_rules.gypi
+++ b/build/filename_rules.gypi
@@ -14,7 +14,7 @@
                     ['exclude', '(^|/)win_[^/]*\\.(h|cc)$'] ],
     }],
     ['OS!="mac" or >(nacl_untrusted_build)==1', {
-      'sources/': [ ['exclude', '_(cocoa|mac)(_unittest)?\\.(h|cc|mm?)$'],
+      'sources/': [ ['exclude', '_(cocoa|mac)(_unittest)?\\.(h|cc|c|mm?)$'],
                     ['exclude', '(^|/)(cocoa|mac)/'] ],
     }],
     ['OS!="ios" or >(nacl_untrusted_build)==1', {
diff --git a/build/ios/grit_whitelist.txt b/build/ios/grit_whitelist.txt
index b86b5d4d..943929d6 100644
--- a/build/ios/grit_whitelist.txt
+++ b/build/ios/grit_whitelist.txt
@@ -720,8 +720,6 @@
 IDS_SYNC_START_SYNC_BUTTON_LABEL
 IDS_SYNC_STATUS_UNRECOVERABLE_ERROR
 IDS_SYNC_STOP_AND_RESTART_SYNC
-IDS_SYNC_TIME_JUST_NOW
-IDS_SYNC_TIME_NEVER
 IDS_SYNC_UNAVAILABLE_ERROR_BUBBLE_VIEW_ACCEPT
 IDS_SYNC_UNAVAILABLE_ERROR_BUBBLE_VIEW_MESSAGE
 IDS_SYNC_UNRECOVERABLE_ERROR_HELP_URL
diff --git a/build/jar_file_jni_generator.gypi b/build/jar_file_jni_generator.gypi
index 3d95b280..71ab006f 100644
--- a/build/jar_file_jni_generator.gypi
+++ b/build/jar_file_jni_generator.gypi
@@ -61,6 +61,11 @@
       'process_outputs_as_sources': 1,
     },
   ],
+  'direct_dependent_settings': {
+    'include_dirs': [
+      '<(SHARED_INTERMEDIATE_DIR)/<(jni_gen_package)',
+    ],
+  },
   # This target exports a hard dependency because it generates header
   # files.
   'hard_dependency': 1,
diff --git a/build/secondary/tools/grit/repack.gni b/build/secondary/tools/grit/repack.gni
index 1030674..673fdf7 100644
--- a/build/secondary/tools/grit/repack.gni
+++ b/build/secondary/tools/grit/repack.gni
@@ -2,6 +2,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+declare_args() {
+  # Absolute path to a resource whitelist (generated using
+  # //tools/resources/find_used_resources.py).
+  repack_whitelist = ""
+}
+
 # This file defines a template to invoke grit repack in a consistent manner.
 #
 # Parameters:
@@ -11,9 +17,6 @@
 #   output  [required]
 #       File name (single string) of the output file.
 #
-#   repack_options  [optional]
-#       List of extra arguments to pass.
-#
 #   deps  [optional]
 #   visibility  [optional]
 #       Normal meaning.
@@ -34,8 +37,11 @@
     ]
 
     args = []
-    if (defined(invoker.repack_options)) {
-      args += invoker.repack_options
+    if (repack_whitelist != "") {
+      assert(
+          repack_whitelist == rebase_path(repack_whitelist),
+          "repack_whitelist must be an absolute path. Current value is $repack_whitelist")
+      args += [ "--whitelist=$repack_whitelist" ]
     }
     args += [ rebase_path(invoker.output, root_build_dir) ]
     args += rebase_path(invoker.sources, root_build_dir)
diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc
index 2ef2896..1c1149d 100644
--- a/cc/layers/delegated_renderer_layer_impl_unittest.cc
+++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc
@@ -45,6 +45,11 @@
     host_impl_->SetViewportSize(gfx::Size(10, 10));
   }
 
+  DrawResult PrepareToDrawFrame(LayerTreeHostImpl::FrameData* frame) {
+    host_impl_->active_tree()->BuildPropertyTreesForTesting();
+    return host_impl_->PrepareToDraw(frame);
+  }
+
  protected:
   FakeImplTaskRunnerProvider task_runner_provider_;
   DebugScopedSetImplThreadAndMainThreadBlocked
@@ -175,7 +180,7 @@
     host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
 
     LayerTreeHostImpl::FrameData frame;
-    EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+    EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
     // Root layer has one render pass, and delegated renderer layer has two
     // contributing render passes and its own render pass.
@@ -197,7 +202,7 @@
     host_impl_->SetViewportDamage(gfx::Rect(10, 10));
 
     LayerTreeHostImpl::FrameData frame;
-    EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+    EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
     // Each non-DelegatedRendererLayer added one RenderPass. The
     // DelegatedRendererLayer added two contributing passes.
@@ -255,7 +260,7 @@
     host_impl_->ActivateSyncTree();
 
     LayerTreeHostImpl::FrameData frame;
-    EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+    EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
     // Root layer has one render pass, and delegated renderer layer has two
     // contributing render passes and its own render pass.
@@ -280,7 +285,7 @@
     host_impl_->ActivateSyncTree();
     host_impl_->SetViewportDamage(gfx::Rect(100, 100));
     LayerTreeHostImpl::FrameData frame;
-    EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+    EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
     // Root layer has one render pass, and delegated renderer layer no longer
     // has contributing render passes.
@@ -293,7 +298,7 @@
 
 TEST_F(DelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // Each non-DelegatedRendererLayer added one RenderPass. The
   // DelegatedRendererLayer added two contributing passes.
@@ -327,7 +332,7 @@
 TEST_F(DelegatedRendererLayerImplTestSimple,
        AddsQuadsToContributingRenderPasses) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // Each non-DelegatedRendererLayer added one RenderPass. The
   // DelegatedRendererLayer added two contributing passes.
@@ -362,7 +367,7 @@
 
 TEST_F(DelegatedRendererLayerImplTestSimple, AddsQuadsToTargetRenderPass) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // Each non-DelegatedRendererLayer added one RenderPass. The
   // DelegatedRendererLayer added two contributing passes.
@@ -390,7 +395,7 @@
 TEST_F(DelegatedRendererLayerImplTestSimple,
        QuadsFromRootRenderPassAreModifiedForTheTarget) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // Each non-DelegatedRendererLayer added one RenderPass. The
   // DelegatedRendererLayer added two contributing passes.
@@ -429,7 +434,7 @@
 
 TEST_F(DelegatedRendererLayerImplTestSimple, RenderPassTransformIsModified) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // The delegated layer has a surface between it and the root.
   EXPECT_TRUE(delegated_renderer_layer_->render_target()->parent());
@@ -470,7 +475,7 @@
 
 TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // Each non-DelegatedRendererLayer added one RenderPass. The
   // DelegatedRendererLayer added two contributing passes and its owned surface
@@ -509,7 +514,7 @@
 TEST_F(DelegatedRendererLayerImplTestOwnSurface,
        AddsQuadsToContributingRenderPasses) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // Each non-DelegatedRendererLayer added one RenderPass. The
   // DelegatedRendererLayer added two contributing passes and its owned surface
@@ -546,7 +551,7 @@
 
 TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsQuadsToTargetRenderPass) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // Each non-DelegatedRendererLayer added one RenderPass. The
   // DelegatedRendererLayer added two contributing passes and its owned surface
@@ -572,7 +577,7 @@
 TEST_F(DelegatedRendererLayerImplTestOwnSurface,
        QuadsFromRootRenderPassAreNotModifiedForTheTarget) {
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   // Each non-DelegatedRendererLayer added one RenderPass. The
   // DelegatedRendererLayer added two contributing passes and its owned surface
@@ -794,7 +799,7 @@
   SetUpTest();
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   const SharedQuadState* root_delegated_shared_quad_state = nullptr;
   const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
@@ -848,7 +853,7 @@
   SetUpTest();
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   const SharedQuadState* root_delegated_shared_quad_state = nullptr;
   const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
@@ -908,7 +913,7 @@
   delegated_renderer_layer_->SetHasRenderSurface(true);
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   const SharedQuadState* root_delegated_shared_quad_state = nullptr;
   const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
@@ -956,7 +961,7 @@
   delegated_renderer_layer_->SetHasRenderSurface(true);
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   const SharedQuadState* root_delegated_shared_quad_state = nullptr;
   const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
@@ -1003,7 +1008,7 @@
   SetUpTest();
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   const SharedQuadState* root_delegated_shared_quad_state = nullptr;
   const SharedQuadState* contrib_delegated_shared_quad_state = nullptr;
@@ -1189,7 +1194,7 @@
   SetUpTest();
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   ASSERT_EQ(2u, frame.render_passes.size());
   const QuadList& contrib_delegated_quad_list =
@@ -1218,7 +1223,7 @@
   SetUpTest();
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   ASSERT_EQ(2u, frame.render_passes.size());
   const QuadList& contrib_delegated_quad_list =
@@ -1248,7 +1253,7 @@
 
   LayerTreeHostImpl::FrameData frame;
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   ASSERT_EQ(2u, frame.render_passes.size());
   const QuadList& contrib_delegated_quad_list =
@@ -1279,7 +1284,7 @@
 
   LayerTreeHostImpl::FrameData frame;
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   ASSERT_EQ(2u, frame.render_passes.size());
   const QuadList& contrib_delegated_quad_list =
@@ -1310,7 +1315,7 @@
   delegated_renderer_layer_->SetHasRenderSurface(true);
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   ASSERT_EQ(3u, frame.render_passes.size());
   const QuadList& contrib_delegated_quad_list =
@@ -1339,7 +1344,7 @@
   delegated_renderer_layer_->SetHasRenderSurface(true);
 
   LayerTreeHostImpl::FrameData frame;
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   ASSERT_EQ(3u, frame.render_passes.size());
   const QuadList& contrib_delegated_quad_list =
@@ -1370,7 +1375,7 @@
 
   LayerTreeHostImpl::FrameData frame;
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   ASSERT_EQ(3u, frame.render_passes.size());
   const QuadList& contrib_delegated_quad_list =
@@ -1399,7 +1404,7 @@
 
   LayerTreeHostImpl::FrameData frame;
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
-  EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
+  EXPECT_EQ(DRAW_SUCCESS, PrepareToDrawFrame(&frame));
 
   ASSERT_EQ(3u, frame.render_passes.size());
   const QuadList& contrib_delegated_quad_list =
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc
index 3c514cdf..8b93be3 100644
--- a/cc/layers/layer_impl_unittest.cc
+++ b/cc/layers/layer_impl_unittest.cc
@@ -263,6 +263,7 @@
   LayerImpl* layer = layer_ptr.get();
   root->AddChild(layer_ptr.Pass());
   layer->SetScrollClipLayer(root->id());
+  host_impl.active_tree()->BuildPropertyTreesForTesting();
   DCHECK(host_impl.CanDraw());
 
   gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
diff --git a/cc/resources/resource_format.cc b/cc/resources/resource_format.cc
index c62ae93..e11c097b 100644
--- a/cc/resources/resource_format.cc
+++ b/cc/resources/resource_format.cc
@@ -89,17 +89,18 @@
 
 gfx::BufferFormat BufferFormat(ResourceFormat format) {
   switch (format) {
-    case RGBA_8888:
-      return gfx::BufferFormat::RGBA_8888;
     case BGRA_8888:
       return gfx::BufferFormat::BGRA_8888;
+    case RED_8:
+      return gfx::BufferFormat::R_8;
     case RGBA_4444:
       return gfx::BufferFormat::RGBA_4444;
+    case RGBA_8888:
+      return gfx::BufferFormat::RGBA_8888;
     case ALPHA_8:
     case LUMINANCE_8:
     case RGB_565:
     case ETC1:
-    case RED_8:
       break;
   }
   NOTREACHED();
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 9ea7b6dd..1cc6538 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -613,6 +613,10 @@
   return GetResource(id)->type;
 }
 
+GLenum ResourceProvider::GetResourceTextureTarget(ResourceId id) {
+  return GetResource(id)->target;
+}
+
 void ResourceProvider::CopyToResource(ResourceId id,
                                       const uint8_t* image,
                                       const gfx::Size& image_size) {
@@ -1448,11 +1452,6 @@
   LazyCreate(GetResource(id));
 }
 
-GLenum ResourceProvider::TargetForTesting(ResourceId id) {
-  Resource* resource = GetResource(id);
-  return resource->target;
-}
-
 void ResourceProvider::LazyCreate(Resource* resource) {
   if (resource->type != RESOURCE_TYPE_GL_TEXTURE ||
       resource->origin != Resource::INTERNAL)
@@ -1502,7 +1501,7 @@
     resource->gpu_memory_buffer =
         gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
                                       size, BufferFormat(format),
-                                      gfx::BufferUsage::SCANOUT)
+                                      gfx::BufferUsage::GPU_READ_CPU_READ_WRITE)
             .release();
     LazyCreateImage(resource);
     resource->dirty_image = true;
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index 39240a1..926647a 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -117,6 +117,7 @@
 
   ResourceType default_resource_type() const { return default_resource_type_; }
   ResourceType GetResourceType(ResourceId id);
+  GLenum GetResourceTextureTarget(ResourceId id);
 
   // Creates a resource of the default resource type.
   ResourceId CreateResource(const gfx::Size& size,
@@ -397,8 +398,6 @@
   // For tests only!
   void CreateForTesting(ResourceId id);
 
-  GLenum TargetForTesting(ResourceId id);
-
   // Sets the current read fence. If a resource is locked for read
   // and has read fences enabled, the resource will not allow writes
   // until this fence has passed.
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index fd322125..1adfe0e 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -168,8 +168,10 @@
 
     gl->GenMailboxCHROMIUM(mailbox.name);
     ResourceProvider::ScopedWriteLockGL lock(resource_provider_, resource_id);
-    gl->ProduceTextureDirectCHROMIUM(lock.texture_id(), GL_TEXTURE_2D,
-                                     mailbox.name);
+    gl->ProduceTextureDirectCHROMIUM(
+        lock.texture_id(),
+        resource_provider_->GetResourceTextureTarget(resource_id),
+        mailbox.name);
   }
   all_resources_.push_front(
       PlaneResource(resource_id, plane_size, format, mailbox));
@@ -384,8 +386,10 @@
       SetPlaneResourceUniqueId(video_frame.get(), i, &plane_resource);
     }
 
-    external_resources.mailboxes.push_back(TextureMailbox(
-        plane_resource.mailbox, gpu::SyncToken(), GL_TEXTURE_2D));
+    external_resources.mailboxes.push_back(
+        TextureMailbox(plane_resource.mailbox, gpu::SyncToken(),
+                       resource_provider_->GetResourceTextureTarget(
+                           plane_resource.resource_id)));
     external_resources.release_callbacks.push_back(
         base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id));
   }
diff --git a/cc/test/fake_delegated_renderer_layer_impl.cc b/cc/test/fake_delegated_renderer_layer_impl.cc
index 9567f14..1984c6f 100644
--- a/cc/test/fake_delegated_renderer_layer_impl.cc
+++ b/cc/test/fake_delegated_renderer_layer_impl.cc
@@ -49,7 +49,7 @@
         TransferableResource resource;
         resource.id = resource_id;
         resource.mailbox_holder.texture_target =
-            resource_provider->TargetForTesting(resource_id);
+            resource_provider->GetResourceTextureTarget(resource_id);
         delegated_frame->resource_list.push_back(resource);
       }
     }
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 7d968a3..d42398a 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -955,7 +955,6 @@
   if (!layer_tree_host_->root_layer()) {
     scoped_refptr<Layer> root_layer = Layer::Create(layer_settings_);
     root_layer->SetBounds(gfx::Size(1, 1));
-    root_layer->SetIsDrawable(true);
     layer_tree_host_->SetRootLayer(root_layer);
   }
 
@@ -963,6 +962,7 @@
   gfx::Size device_root_bounds = gfx::ScaleToCeiledSize(
       root_bounds, layer_tree_host_->device_scale_factor());
   layer_tree_host_->SetViewportSize(device_root_bounds);
+  layer_tree_host_->root_layer()->SetIsDrawable(true);
 }
 
 void LayerTreeTest::Timeout() {
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc
index 0a06830..eb81afa 100644
--- a/cc/tiles/tile_manager_unittest.cc
+++ b/cc/tiles/tile_manager_unittest.cc
@@ -1685,6 +1685,7 @@
   pending_tree->SetRootLayer(pending_layer.Pass());
 
   // Add tilings/tiles for the layer.
+  host_impl_->pending_tree()->BuildPropertyTreesForTesting();
   host_impl_->pending_tree()->UpdateDrawProperties(false /* update_lcd_text */);
 
   // Build the raster queue and invalidate the top tile.
@@ -1776,6 +1777,7 @@
   pending_tree->SetRootLayer(pending_layer.Pass());
 
   // Add tilings/tiles for the layer.
+  host_impl->pending_tree()->BuildPropertyTreesForTesting();
   host_impl->pending_tree()->UpdateDrawProperties(false /* update_lcd_text */);
 
   // Build the raster queue and invalidate the top tile.
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 5ecd1b8..2ea5b2ad 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -3258,6 +3258,7 @@
   host_impl.active_tree()->SetRootLayer(root.Pass());
   host_impl.SetVisible(true);
   host_impl.InitializeRenderer(output_surface.get());
+  host_impl.active_tree()->BuildPropertyTreesForTesting();
   bool update_lcd_text = false;
   host_impl.active_tree()->UpdateDrawProperties(update_lcd_text);
 
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index dc94e6e..d3c82dd 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -924,6 +924,7 @@
   LayerImpl* root = host_impl_->active_tree()->root_layer();
   root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
   root->SetPosition(gfx::PointF(-25.f, 0.f));
+  root->SetDrawsContent(true);
 
   DrawFrame();
 
@@ -1262,7 +1263,9 @@
   CreateBasicVirtualViewportLayers(viewport_size, content_size);
 
   LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
+  outer_scroll_layer->SetDrawsContent(true);
   LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
+  inner_scroll_layer->SetDrawsContent(true);
 
   EXPECT_VECTOR_EQ(
       gfx::Vector2dF(500, 500),
@@ -1321,7 +1324,9 @@
   CreateBasicVirtualViewportLayers(viewport_size, content_size);
 
   LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
+  outer_scroll_layer->SetDrawsContent(true);
   LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
+  inner_scroll_layer->SetDrawsContent(true);
 
   // Sanity checks.
   EXPECT_VECTOR_EQ(
@@ -1371,7 +1376,9 @@
   CreateBasicVirtualViewportLayers(viewport_size, content_size);
 
   LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer();
+  outer_scroll_layer->SetDrawsContent(true);
   LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer();
+  inner_scroll_layer->SetDrawsContent(true);
 
   EXPECT_VECTOR_EQ(
       gfx::Vector2dF(500, 500),
@@ -3472,10 +3479,12 @@
 
   LayerImpl* inner_scroll =
       host_impl_->active_tree()->InnerViewportScrollLayer();
+  inner_scroll->SetDrawsContent(true);
   LayerImpl* inner_container =
       host_impl_->active_tree()->InnerViewportContainerLayer();
   LayerImpl* outer_scroll =
       host_impl_->active_tree()->OuterViewportScrollLayer();
+  outer_scroll->SetDrawsContent(true);
   LayerImpl* outer_container =
       host_impl_->active_tree()->OuterViewportContainerLayer();
 
@@ -3639,6 +3648,8 @@
 
   // Scroll 25px to hide top controls
   gfx::Vector2dF scroll_delta(0.f, 25.f);
+  host_impl_->active_tree()->property_trees()->needs_rebuild = true;
+  host_impl_->active_tree()->BuildPropertyTreesForTesting();
   EXPECT_EQ(InputHandler::SCROLL_STARTED,
             host_impl_->ScrollBegin(gfx::Point(), InputHandler::GESTURE));
   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
@@ -4214,8 +4225,10 @@
 
   // Create a normal scrollable root layer and another scrollable child layer.
   LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size);
+  scroll->SetDrawsContent(true);
   LayerImpl* root = host_impl_->active_tree()->root_layer();
   LayerImpl* child = scroll->children()[0];
+  child->SetDrawsContent(true);
 
   scoped_ptr<LayerImpl> scrollable_child_clip =
       LayerImpl::Create(host_impl_->active_tree(), 6);
@@ -4224,6 +4237,7 @@
   scrollable_child_clip->AddChild(scrollable_child.Pass());
   child->AddChild(scrollable_child_clip.Pass());
   LayerImpl* grand_child = child->children()[0];
+  grand_child->SetDrawsContent(true);
 
   // Set new page scale on impl thread by pinching.
   RebuildPropertyTrees();
@@ -4533,6 +4547,7 @@
 
 TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
+  scroll_layer->SetDrawsContent(true);
 
   // Rotate the root layer 90 degrees counter-clockwise about its center.
   gfx::Transform rotate_transform;
@@ -4724,6 +4739,7 @@
 TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
   LayerImpl* scroll_layer =
       SetupScrollAndContentsLayers(gfx::Size(100, 100));
+  scroll_layer->SetDrawsContent(true);
 
   // Scale the layer to twice its normal size.
   int scale = 2;
@@ -4948,6 +4964,7 @@
   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
   LayerImpl* clip_layer = scroll_layer->parent()->parent();
   clip_layer->SetBounds(gfx::Size(10, 20));
+  scroll_layer->SetDrawsContent(true);
 
   // Draw first frame to clear any pending draws and check scroll.
   DrawFrame();
@@ -5233,15 +5250,15 @@
     scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
     EXPECT_TRUE(scroll_result.did_scroll);
     EXPECT_TRUE(scroll_result.did_overscroll_root);
-    EXPECT_EQ(gfx::Vector2dF(0.000000f, 17.699997f).ToString(),
-              host_impl_->accumulated_root_overscroll().ToString());
+    EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.000000f, 17.699997f),
+                        host_impl_->accumulated_root_overscroll());
 
     scroll_result =
         host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f, -0.01f));
     EXPECT_FALSE(scroll_result.did_scroll);
     EXPECT_FALSE(scroll_result.did_overscroll_root);
-    EXPECT_EQ(gfx::Vector2dF(0.000000f, 17.699997f).ToString(),
-              host_impl_->accumulated_root_overscroll().ToString());
+    EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.000000f, 17.699997f),
+                        host_impl_->accumulated_root_overscroll());
     host_impl_->ScrollEnd();
     // TestCase to check  kEpsilon, which prevents minute values to trigger
     // gloweffect without reaching edge.
@@ -5921,6 +5938,7 @@
   LayerTreeHostImpl::FrameData frame;
 
   // First frame, the entire screen should get swapped.
+  layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
   EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
   layer_tree_host_impl->DrawLayers(&frame);
   layer_tree_host_impl->DidDrawAllLayers(frame);
@@ -5935,6 +5953,8 @@
   // expected swap rect: vertically flipped, with origin at bottom left corner.
   layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition(
       gfx::PointF());
+  layer_tree_host_impl->active_tree()->property_trees()->needs_rebuild = true;
+  layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
   EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
   layer_tree_host_impl->DrawLayers(&frame);
   host_impl_->DidDrawAllLayers(frame);
@@ -6241,6 +6261,7 @@
   root->AddChild(child.Pass());
 
   my_host_impl->active_tree()->SetRootLayer(root.Pass());
+  my_host_impl->active_tree()->BuildPropertyTreesForTesting();
   return my_host_impl.Pass();
 }
 
@@ -8210,6 +8231,7 @@
   const gfx::Rect external_clip(layer_size);
   const bool resourceless_software_draw = false;
   LayerImpl* layer = SetupScrollAndContentsLayers(layer_size);
+  layer->SetDrawsContent(true);
 
   host_impl_->SetExternalDrawConstraints(external_transform,
                                          external_viewport,
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 696c8d9..a1d5be2 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -2319,7 +2319,7 @@
     EXPECT_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
     EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id());
     EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
-              resource_provider->TargetForTesting(
+              resource_provider->GetResourceTextureTarget(
                   io_surface_draw_quad->io_surface_resource_id()));
 
     if (delegating_renderer()) {
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc
index 34942c2..bffdbaf 100644
--- a/cc/trees/layer_tree_impl_unittest.cc
+++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -14,6 +14,7 @@
 #include "cc/test/layer_tree_host_common_test.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/test/test_task_graph_runner.h"
+#include "cc/trees/draw_property_utils.h"
 #include "cc/trees/layer_tree_host_impl.h"
 #include "ui/gfx/geometry/size_conversions.h"
 
@@ -1872,8 +1873,11 @@
           test_point);
   EXPECT_FALSE(result_layer);
   EXPECT_FALSE(test_layer->IsDrawnRenderSurfaceLayerListMember());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform,
-                                  test_layer->screen_space_transform());
+  EXPECT_TRANSFORMATION_MATRIX_EQ(
+      expected_screen_space_transform,
+      ScreenSpaceTransformFromPropertyTrees(
+          test_layer,
+          host_impl().active_tree()->property_trees()->transform_tree));
 
   // We change the position of the test layer such that the test point is now
   // inside the test_layer.
@@ -1890,8 +1894,11 @@
   ASSERT_TRUE(result_layer);
   ASSERT_EQ(test_layer, result_layer);
   EXPECT_FALSE(result_layer->IsDrawnRenderSurfaceLayerListMember());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform,
-                                  result_layer->screen_space_transform());
+  EXPECT_TRANSFORMATION_MATRIX_EQ(
+      expected_screen_space_transform,
+      ScreenSpaceTransformFromPropertyTrees(
+          test_layer,
+          host_impl().active_tree()->property_trees()->transform_tree));
 }
 
 TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) {
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 07163d9..11b1450e 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -209,7 +209,7 @@
     }
 
     if (is_mac) {
-      sources += [ "app/chrome_exe_main_mac.cc" ]
+      sources += [ "app/chrome_exe_main_mac.c" ]
       deps += [ ":chrome_dll" ]
 
       # TODO(GYP) lots more stuff in the is_mac block.
@@ -220,7 +220,7 @@
         ":packed_resources",
       ]
       deps += [
-        "//components/startup_metric_utils/browser",
+        "//components/startup_metric_utils",
 
         # Precompiled plugins that need to get copied to the output directory.
         # On Mac, internal plugins go inside the framework, so these
diff --git a/chrome/VERSION b/chrome/VERSION
index c104260..cf05668 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=48
 MINOR=0
-BUILD=2556
+BUILD=2557
 PATCH=0
diff --git a/chrome/android/java/res/layout/infobar_control_toggle.xml b/chrome/android/java/res/layout/infobar_control_toggle.xml
new file mode 100644
index 0000000..47a2b927
--- /dev/null
+++ b/chrome/android/java/res/layout/infobar_control_toggle.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2015 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/subcontrol_toggle"
+    android:layout_width="match_parent"
+    android:layout_height="36dp"
+    android:gravity="center_vertical">
+
+    <ImageView
+        android:id="@+id/control_toggle_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_marginEnd="8dp"
+        android:scaleType="centerInside"
+        android:contentDescription="@null" />
+
+    <TextView
+        android:id="@+id/control_toggle_message"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:gravity="center_vertical"
+        android:lineSpacingMultiplier="1.4"
+        android:textSize="@dimen/infobar_control_text_size"
+        android:textColor="@color/default_text_color" />
+
+    <Switch
+        android:id="@+id/control_toggle_switch"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_marginStart="16dp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index fff9518..3a1442f 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -68,6 +68,8 @@
     <dimen name="infobar_margin">16dp</dimen>
     <!-- Width and height of the infobar icon. -->
     <dimen name="infobar_icon_size">36dp</dimen>
+    <!-- Text size for controls on the infobar (e.g. toggles or informational text). -->
+    <dimen name="infobar_control_text_size">14sp</dimen>
 
     <!-- App banner dimensions -->
     <dimen name="app_banner_icon_spacing">16dp</dimen>
diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml
index e049d9e..e10aeeaf 100644
--- a/chrome/android/java/res/values/ids.xml
+++ b/chrome/android/java/res/values/ids.xml
@@ -17,4 +17,5 @@
     <item name="refine_view_id" type="id"/>
     <item name="tabswitcher_multiple_drawable" type="id"/>
     <item name="tabswitcher_single_drawable" type="id"/>
+    <item name="translate_infobar_always_toggle" type="id"/>
 </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
index 4d52412..6cc9cbb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
@@ -13,6 +13,7 @@
 import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content_public.common.TopControlsState;
 import org.chromium.ui.resources.ResourceManager;
 
 /**
@@ -186,6 +187,7 @@
      * Create a new OverlayPanelContent object. This can be overridden for tests.
      * @return A new OverlayPanelContent object.
      */
+    @Override
     public OverlayPanelContent createNewOverlayPanelContent() {
         return new OverlayPanelContent(new OverlayContentDelegate(),
                 new OverlayContentProgressObserver(), mActivity);
@@ -413,11 +415,7 @@
      */
     protected void handleBarClick(long time, float x, float y) {
         if (isPeeking()) {
-            if (supportsExpandedState()) {
-                expandPanel(StateChangeReason.SEARCH_BAR_TAP);
-            } else {
-                maximizePanel(StateChangeReason.SEARCH_BAR_TAP);
-            }
+            expandPanel(StateChangeReason.SEARCH_BAR_TAP);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContentViewDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContentViewDelegate.java
new file mode 100644
index 0000000..9eafea9
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContentViewDelegate.java
@@ -0,0 +1,23 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.compositor.bottombar;
+
+import org.chromium.content.browser.ContentViewCore;
+
+/**
+ * The delegate that is notified when the OverlayPanel ContentViewCore is ready to be rendered.
+ */
+public interface OverlayPanelContentViewDelegate {
+    /**
+     * Sets the {@code ContentViewCore} associated to the OverlayPanel.
+     * @param contentViewCore Reference to the ContentViewCore.
+     */
+    void setOverlayPanelContentViewCore(ContentViewCore contentViewCore);
+
+    /**
+     * Releases the {@code ContentViewCore} associated to the OverlayPanel.
+     */
+    void releaseOverlayPanelContentViewCore();
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
index 0457f9e..45c795d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -77,6 +77,7 @@
     /**
      * Destroy the panel's components.
      */
+    @Override
     public void destroy() {
         super.destroy();
         destroyPromoView();
@@ -300,15 +301,6 @@
     }
 
     // ============================================================================================
-    // Panel base methods
-    // ============================================================================================
-
-    @Override
-    protected boolean supportsExpandedState() {
-        return isFullscreenSizePanel();
-    }
-
-    // ============================================================================================
     // Animation Handling
     // ============================================================================================
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelAnimation.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelAnimation.java
index 8837cde..22acc3b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelAnimation.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelAnimation.java
@@ -255,7 +255,7 @@
         // maximized so this project state change is not needed.
         if (projectedState == PanelState.MAXIMIZED
                 && getPanelState() == PanelState.PEEKED
-                && isPromoVisible() && supportsExpandedState()) {
+                && isPromoVisible()) {
             projectedState = PanelState.EXPANDED;
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelBase.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelBase.java
index 7af52d2a4..5e838bf9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelBase.java
@@ -46,18 +46,6 @@
     private static final float EXPANDED_PANEL_HEIGHT_PERCENTAGE = .7f;
 
     /**
-     * The height of the expanded Search Panel relative to the height of the screen when
-     * the panel is in the narrow width mode.
-     */
-    private static final float NARROW_EXPANDED_PANEL_HEIGHT_PERCENTAGE = .6f;
-
-    /**
-     * The height of the maximized Search Panel relative to the height of the screen when
-     * the panel is in the narrow width mode.
-     */
-    private static final float NARROW_MAXIMIZED_PANEL_HEIGHT_PERCENTAGE = .9f;
-
-    /**
      * The width of the small version of the Search Panel in dps.
      */
     private static final float SMALL_PANEL_WIDTH_DP = 600.f;
@@ -544,14 +532,6 @@
         return mIsMaximized;
     }
 
-    /**
-     * Get if the panel supports an expanded state. This should be overridden in child classes.
-     * @return True if the panel supports an EXPANDED state.
-     */
-    protected boolean supportsExpandedState() {
-        return false;
-    }
-
     // --------------------------------------------------------------------------------------------
     // Contextual Search Bar states
     // --------------------------------------------------------------------------------------------
@@ -813,8 +793,7 @@
         if (state == PanelState.CLOSED) {
             mIsShowing = false;
             onClosed(reason);
-        } else if (state == PanelState.EXPANDED && isFullscreenSizePanel()
-                || (state == PanelState.MAXIMIZED && !isFullscreenSizePanel())) {
+        } else if (state == PanelState.EXPANDED) {
             showPromoViewAtYPosition(getPromoYPx());
         }
 
@@ -889,13 +868,14 @@
             if (isFullscreenSizePanel()) {
                 panelHeight = fullscreenHeight * EXPANDED_PANEL_HEIGHT_PERCENTAGE;
             } else {
-                panelHeight = mLayoutHeight * NARROW_EXPANDED_PANEL_HEIGHT_PERCENTAGE;
+                panelHeight = (fullscreenHeight - mToolbarHeight)
+                        * EXPANDED_PANEL_HEIGHT_PERCENTAGE;
             }
         } else if (state == PanelState.MAXIMIZED) {
             if (isFullscreenSizePanel()) {
                 panelHeight = fullscreenHeight;
             } else {
-                panelHeight = mLayoutHeight * NARROW_MAXIMIZED_PANEL_HEIGHT_PERCENTAGE;
+                panelHeight = fullscreenHeight - mToolbarHeight;
             }
         }
 
@@ -919,9 +899,6 @@
             if (!isValidState(state)) {
                 continue;
             }
-            if (!isFullscreenSizePanel() && state == PanelState.EXPANDED) {
-                continue;
-            }
 
             float height = getPanelHeightFromState(state);
             float heightDiff = Math.abs(desiredPanelHeight - height);
@@ -1170,8 +1147,7 @@
      */
     protected void updatePanelForMaximization(float percentage) {
         // Update the opt out promo.
-        float promoVisibilityPercentage = isFullscreenSizePanel() ? 1.f - percentage : 1.f;
-        updatePromoVisibility(promoVisibilityPercentage);
+        updatePromoVisibility(1.f - percentage);
 
         // Base page offset.
         mBasePageY = getBasePageTargetY();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerDocument.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerDocument.java
index 289b348..c65a3d1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerDocument.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerDocument.java
@@ -14,6 +14,7 @@
 
 import org.chromium.chrome.browser.ChromeApplication;
 import org.chromium.chrome.browser.UrlConstants;
+import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelContentViewDelegate;
 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel;
 import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
 import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
@@ -29,7 +30,6 @@
 import org.chromium.chrome.browser.compositor.layouts.phone.ContextualSearchLayout;
 import org.chromium.chrome.browser.compositor.overlays.SceneOverlay;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate;
-import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager.ContextualSearchContentViewDelegate;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchStaticEventFilter;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchStaticEventFilter.ContextualSearchTapHandler;
 import org.chromium.chrome.browser.device.DeviceClassManager;
@@ -58,7 +58,7 @@
  * driving all {@link Layout}s that get shown via the {@link LayoutManager}.
  */
 public class LayoutManagerDocument extends LayoutManager
-        implements ContextualSearchTapHandler, ContextualSearchContentViewDelegate,
+        implements ContextualSearchTapHandler, OverlayPanelContentViewDelegate,
                 ReaderModeTapHandler {
     // Layouts
     /** A {@link Layout} used for showing a normal web page. */
@@ -331,12 +331,12 @@
     }
 
     @Override
-    public void setContextualSearchContentViewCore(ContentViewCore contentViewCore) {
+    public void setOverlayPanelContentViewCore(ContentViewCore contentViewCore) {
         mHost.onContentViewCoreAdded(contentViewCore);
     }
 
     @Override
-    public void releaseContextualSearchContentViewCore() {
+    public void releaseOverlayPanelContentViewCore() {
         if (getTabModelSelector() == null) return;
         Tab tab = getTabModelSelector().getCurrentTab();
         if (tab != null) tab.updateFullscreenEnabledState();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java
index 0c07e65..210cf45 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java
@@ -9,6 +9,7 @@
 
 import org.chromium.base.CommandLine;
 import org.chromium.base.SysUtils;
+import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ChromeVersionInfo;
 import org.chromium.components.variations.VariationsAssociatedData;
@@ -36,6 +37,11 @@
 
     static final String DISABLE_EXTRA_SEARCH_BAR_ANIMATIONS = "disable_extra_search_bar_animations";
 
+    // Translation.
+    @VisibleForTesting
+    static final String TRANSLATION_ONEBOX_ENABLED = "translation_onebox_enabled";
+
+    // Tap handling.
     private static final int UNLIMITED_TAPS = -1;
     private static final int DEFAULT_TAP_RESOLVE_LIMIT_FOR_DECIDED = UNLIMITED_TAPS;
     private static final int DEFAULT_TAP_PREFETCH_LIMIT_FOR_DECIDED = UNLIMITED_TAPS;
@@ -46,6 +52,7 @@
     private static Boolean sEnabled;
     private static Boolean sIsPeekPromoEnabled;
     private static Integer sPeekPromoMaxCount;
+    private static Boolean sIsTranslationOneboxEnabled;
 
     /**
      * Don't instantiate.
@@ -214,6 +221,16 @@
         return sPeekPromoMaxCount.intValue();
     }
 
+    /**
+     * @return Whether triggering a translation Onebox in the SERP is enabled.
+     */
+    static boolean isTranslationOneboxEnabled() {
+        if (sIsTranslationOneboxEnabled == null) {
+            sIsTranslationOneboxEnabled = getBooleanParam(TRANSLATION_ONEBOX_ENABLED);
+        }
+        return sIsTranslationOneboxEnabled.booleanValue();
+    }
+
     // --------------------------------------------------------------------------------------------
     // Helpers.
     // --------------------------------------------------------------------------------------------
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
index 8f28b28..2943b2b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.contextualsearch;
 
 import android.app.Activity;
+import android.content.Context;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
@@ -21,6 +22,7 @@
 import org.chromium.chrome.browser.compositor.bottombar.OverlayContentDelegate;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState;
 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason;
+import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelContentViewDelegate;
 import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchSelectionController.SelectionType;
 import org.chromium.chrome.browser.device.DeviceClassManager;
@@ -48,10 +50,16 @@
 import org.chromium.content_public.browser.NavigationEntry;
 import org.chromium.content_public.browser.WebContentsObserver;
 import org.chromium.content_public.common.TopControlsState;
+import org.chromium.ui.UiUtils;
 import org.chromium.ui.base.WindowAndroid;
 
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
 
 import javax.annotation.Nullable;
 
@@ -88,7 +96,7 @@
 
     private final WindowAndroid mWindowAndroid;
     private WebContentsObserver mSearchWebContentsObserver;
-    private ContextualSearchContentViewDelegate mSearchContentViewDelegate;
+    private OverlayPanelContentViewDelegate mSearchContentViewDelegate;
     private final ContextualSearchTabPromotionDelegate mTabPromotionDelegate;
     private TabModelSelectorTabObserver mTabModelSelectorTabObserver;
     private TabModelObserver mTabModelObserver;
@@ -114,6 +122,9 @@
     private boolean mIsShowingPromo;
     private boolean mDidLogPromoOutcome;
 
+    // Cached target languages for translation;
+    private List<String> mTargetLanguages;
+
     /**
      * Whether contextual search manager is currently promoting a tab. We should be ignoring hide
      * requests when mIsPromotingTab is set to true.
@@ -135,22 +146,6 @@
     private TabRedirectHandler mTabRedirectHandler;
 
     /**
-     * The delegate that is notified when the Search Panel ContentViewCore is ready to be rendered.
-     */
-    public interface ContextualSearchContentViewDelegate {
-        /**
-         * Sets the {@code ContentViewCore} associated to the Contextual Search Panel.
-         * @param contentViewCore Reference to the ContentViewCore.
-         */
-        void setContextualSearchContentViewCore(ContentViewCore contentViewCore);
-
-        /**
-         * Releases the {@code ContentViewCore} associated to the Contextual Search Panel.
-         */
-        void releaseContextualSearchContentViewCore();
-    }
-
-    /**
      * The delegate that is responsible for promoting a {@link ContentViewCore} to a {@link Tab}
      * when necessary.
      */
@@ -290,13 +285,21 @@
     }
 
     /**
-     * Sets the selection controller for testing purposes.
+     * @return The selection controller, for testing purposes.
      */
     @VisibleForTesting
     ContextualSearchSelectionController getSelectionController() {
         return mSelectionController;
     }
 
+    /**
+     * @return The current search request, or {@code null} if there is none, for testing.
+     */
+    @VisibleForTesting
+    ContextualSearchRequest getRequest() {
+        return mSearchRequest;
+    }
+
     @VisibleForTesting
     boolean isSearchPanelShowing() {
         return mSearchPanel.isShowing();
@@ -476,10 +479,13 @@
             mNetworkCommunicator.startSearchTermResolutionRequest(
                     mSelectionController.getSelectedText());
             didRequestSurroundings = true;
+            // Cache the target languages in case they are needed for translation.
+            if (mPolicy.isTranslationEnabled()) getTargetLanguages();
         } else {
             boolean shouldPrefetch = mPolicy.shouldPrefetchSearchResult(isTap);
             mSearchRequest = new ContextualSearchRequest(mSelectionController.getSelectedText(),
                     null, shouldPrefetch);
+            // TODO(donnd): figure out a way to do translation on long-press selections.
             mDidStartLoadingResolvedSearchRequest = false;
             mSearchPanel.displaySearchTerm(mSelectionController.getSelectedText());
             if (shouldPrefetch) loadSearchUrl();
@@ -675,20 +681,22 @@
      *        selection should be expanded by.
      * @param selectionEndAdjust A positive number of characters that the end of the existing
      *        selection should be expanded by.
+     * @param contextLanguage The language of the original search term, or an empty string.
      */
     @CalledByNative
     public void onSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
             final String searchTerm, final String displayText, final String alternateTerm,
-            boolean doPreventPreload, int selectionStartAdjust, int selectionEndAdjust) {
+            boolean doPreventPreload, int selectionStartAdjust, int selectionEndAdjust,
+            final String contextLanguage) {
         mNetworkCommunicator.handleSearchTermResolutionResponse(isNetworkUnavailable, responseCode,
                 searchTerm, displayText, alternateTerm, doPreventPreload, selectionStartAdjust,
-                selectionEndAdjust);
+                selectionEndAdjust, contextLanguage);
     }
 
     @Override
     public void handleSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
             String searchTerm, String displayText, String alternateTerm, boolean doPreventPreload,
-            int selectionStartAdjust, int selectionEndAdjust) {
+            int selectionStartAdjust, int selectionEndAdjust, String contextLanguage) {
         if (!mSearchPanel.isShowing()) return;
 
         // Show an appropriate message for what to search for.
@@ -721,6 +729,14 @@
             // appear in the user's history until the user views it).  See crbug.com/406446.
             boolean shouldPreload = !doPreventPreload && mPolicy.shouldPrefetchSearchResult(true);
             mSearchRequest = new ContextualSearchRequest(searchTerm, alternateTerm, shouldPreload);
+            // Trigger translation, if enabled.
+            if (!contextLanguage.isEmpty() && mPolicy.isTranslationEnabled()) {
+                List<String> targetLanguages = getTargetLanguages();
+                if (mPolicy.needsTranslation(contextLanguage, targetLanguages)) {
+                    mSearchRequest.forceTranslation(
+                            contextLanguage, mPolicy.bestTargetLanguage(targetLanguages));
+                }
+            }
             mDidStartLoadingResolvedSearchRequest = false;
             if (mSearchPanel.isContentShowing()) {
                 mSearchRequest.setNormalPriority();
@@ -769,6 +785,68 @@
     }
 
     // ============================================================================================
+    // Translation support
+    // ============================================================================================
+
+    /**
+     * Gets the list of target languages for the current user, with the first
+     * item in the list being the user's primary language.
+     * @return The {@link List} of languages the user understands with their primary language first.
+     */
+    private List<String> getTargetLanguages() {
+        // May be cached.
+        if (mTargetLanguages != null) return mTargetLanguages;
+
+        // Using LinkedHashSet keeps the entries both unique and ordered.
+        Set<String> uniqueLanguages = new LinkedHashSet<String>();
+
+        // The primary language always comes first.
+        uniqueLanguages.add(
+                trimLocaleToLanguage(nativeGetTargetLanguage(mNativeContextualSearchManagerPtr)));
+
+        // Next add languages the user knows how to type.
+        Context context = mActivity.getApplicationContext();
+        List<String> locales = context != null
+                ? new ArrayList<String>(UiUtils.getIMELocales(context))
+                : new ArrayList<String>();
+        for (int i = 0; i < locales.size(); i++) {
+            uniqueLanguages.add(trimLocaleToLanguage(locales.get(i)));
+        }
+
+        // Add the accept languages last, since they are a weaker hint than presence of a keyboard.
+        List<String> acceptLanguages = getAcceptLanguages();
+        for (int i = 0; i < acceptLanguages.size(); i++) {
+            uniqueLanguages.add(trimLocaleToLanguage(acceptLanguages.get(i)));
+        }
+        mTargetLanguages = new ArrayList<String>(uniqueLanguages);
+        return mTargetLanguages;
+    }
+
+    /**
+     * Gets the list of accept languages for this user.
+     * @return The {@link List} of languages the user understands or does not want translated.
+     */
+    private List<String> getAcceptLanguages() {
+        String acceptLanguages = nativeGetAcceptLanguages(mNativeContextualSearchManagerPtr);
+        List<String> result = new ArrayList<String>();
+        for (String language : acceptLanguages.split(",")) {
+            result.add(language);
+        }
+        return result;
+    }
+
+    /**
+     * @return The given locale as a language code.
+     */
+    private String trimLocaleToLanguage(String locale) {
+        // TODO(donnd): use getScript or getLanguageTag (both API 21), or some other standard way to
+        // strip the country, instead of hard-coding the two character language code.
+        // TODO(donnd): Shouldn't getLanguage() do this?
+        String trimmedLocale = locale.substring(0, 2);
+        return new Locale(trimmedLocale).getLanguage();
+    }
+
+    // ============================================================================================
     // OverlayContentDelegate
     // ============================================================================================
 
@@ -854,13 +932,13 @@
         @Override
         public void onContentViewCreated(ContentViewCore contentViewCore) {
             // TODO(mdjones): Move SearchContentViewDelegate ownership to panel.
-            mSearchContentViewDelegate.setContextualSearchContentViewCore(contentViewCore);
+            mSearchContentViewDelegate.setOverlayPanelContentViewCore(contentViewCore);
         }
 
         @Override
         public void onContentViewDestroyed() {
             if (mSearchContentViewDelegate != null) {
-                mSearchContentViewDelegate.releaseContextualSearchContentViewCore();
+                mSearchContentViewDelegate.releaseOverlayPanelContentViewCore();
             }
         }
 
@@ -901,10 +979,10 @@
     // --------------------------------------------------------------------------------------------
 
     /**
-     * Sets the {@code ContextualSearchContentViewDelegate} associated with the Content View.
+     * Sets the {@code OverlayPanelContentViewDelegate} associated with the Content View.
      * @param delegate
      */
-    public void setSearchContentViewDelegate(ContextualSearchContentViewDelegate delegate) {
+    public void setSearchContentViewDelegate(OverlayPanelContentViewDelegate delegate) {
         mSearchContentViewDelegate = delegate;
     }
 
@@ -1194,4 +1272,6 @@
     private native void nativeGatherSurroundingText(long nativeContextualSearchManager,
             String selection, boolean useResolvedSearchTerm, ContentViewCore baseContentViewCore,
             boolean maySendBasePageUrl);
+    private native String nativeGetTargetLanguage(long nativeContextualSearchManager);
+    private native String nativeGetAcceptLanguages(long nativeContextualSearchManager);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchNetworkCommunicator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchNetworkCommunicator.java
index 598b489..2ccbc6b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchNetworkCommunicator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchNetworkCommunicator.java
@@ -33,10 +33,11 @@
      *        the search term.
      * @param selectionEndAdjust The end offset adjustment of the selection to use to highlight
      *        the search term.
+     * @param contextLanguage The language of the context, or the empty string if unknown.
      */
     void handleSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
             String searchTerm, String displayText, String alternateTerm, boolean doPreventPreload,
-            int selectionStartAdjust, int selectionEndAdjust);
+            int selectionStartAdjust, int selectionEndAdjust, String contextLanguage);
 
     // --------------------------------------------------------------------------------------------
     // These are non-network actions that need to be stubbed out for testing.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
index 10fcbdbe..7485710 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.contextualsearch;
 
 import android.content.Context;
+import android.text.TextUtils;
 
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.browser.ChromeVersionInfo;
@@ -15,6 +16,8 @@
 import org.chromium.content.browser.ContentViewCore;
 
 import java.net.URL;
+import java.util.List;
+import java.util.Locale;
 import java.util.regex.Pattern;
 
 import javax.annotation.Nullable;
@@ -387,6 +390,45 @@
         return mPreferenceManager.getContextualSearchTapCount();
     }
 
+    /**
+     * Determines whether translation is needed between the given languages.
+     * @param sourceLanguage The source language code; language we're translating from.
+     * @param targetLanguages A list of target language codes; languages we might translate to.
+     * @return Whether translation is needed or not.
+     */
+    boolean needsTranslation(String sourceLanguage, List<String> targetLanguages) {
+        // For now, we just look for a language match.
+        for (String targetLanguage : targetLanguages) {
+            if (TextUtils.equals(sourceLanguage, targetLanguage)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Determines the best target language.
+     */
+    String bestTargetLanguage(List<String> targetLanguages) {
+        // For now, we just return the first language, unless it's English (due to over-usage).
+        // TODO(donnd): Improve this logic. Determining the right language seems non-trivial.
+        // E.g. If this language doesn't match the user's server preferences, they might see a page
+        // in one language and the one box translation in another, which might be confusing.
+        if (TextUtils.equals(targetLanguages.get(0), Locale.ENGLISH.getLanguage())
+                && targetLanguages.size() > 1) {
+            return targetLanguages.get(1);
+        } else {
+            return targetLanguages.get(0);
+        }
+    }
+
+    /**
+     * @return Whether translation should be enabled or not.
+     */
+    boolean isTranslationEnabled() {
+        return ContextualSearchFieldTrial.isTranslationOneboxEnabled();
+    }
+
     // --------------------------------------------------------------------------------------------
     // Private helpers.
     // --------------------------------------------------------------------------------------------
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRequest.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRequest.java
index 0b9bb03e..614a818b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRequest.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRequest.java
@@ -5,11 +5,14 @@
 package org.chromium.chrome.browser.contextualsearch;
 
 import android.net.Uri;
+import android.text.TextUtils;
 
+import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.browser.search_engines.TemplateUrlService;
 
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Locale;
 
 import javax.annotation.Nullable;
 
@@ -19,16 +22,24 @@
  * fall-back when the low-priority version fails, and tracks which one is in use.
  */
 class ContextualSearchRequest {
-
-    private final Uri mLowPriorityUri;
-    private final Uri mNormalPriorityUri;
     private final boolean mWasPrefetch;
 
+    private Uri mLowPriorityUri;
+    private Uri mNormalPriorityUri;
+
     private boolean mIsLowPriority;
     private boolean mHasFailedLowPriorityLoad;
+    private boolean mIsTranslationForced;
 
+    private static final String GWS_LOW_PRIORITY_SEARCH_PATH = "s";
+    private static final String GWS_SEARCH_NO_SUGGESTIONS_PARAM = "sns";
+    private static final String GWS_SEARCH_NO_SUGGESTIONS_PARAM_VALUE = "1";
+    private static final String GWS_QUERY_PARAM = "q";
     private static final String CTXS_PARAM_PATTERN = "(ctxs=[^&]+)";
     private static final String CTXR_PARAM = "ctxr";
+    @VisibleForTesting static final String TLITE_SOURCE_LANGUAGE_PARAM = "tlitesl";
+    private static final String TLITE_TARGET_LANGUAGE_PARAM = "tlitetl";
+    private static final String TLITE_QUERY_PARAM = "tlitetxt";
 
     /**
      * Creates a search request for the given search term without any alternate term and
@@ -53,10 +64,7 @@
         if (isLowPriorityEnabled) {
             // TODO(donnd): Call TemplateURL once we have an API for 3rd-party providers.
             Uri baseLowPriorityUri = getUriTemplate(searchTerm, alternateTerm, true);
-            mLowPriorityUri = baseLowPriorityUri.buildUpon()
-                .path("s")
-                .appendQueryParameter("sns", "1")
-                .build();
+            mLowPriorityUri = makeLowPriorityUri(baseLowPriorityUri);
             mIsLowPriority = true;
         } else {
             mIsLowPriority = false;
@@ -140,18 +148,94 @@
     }
 
     /**
+     * Adds translation parameters.
+     * @param sourceLanguage The language of the original search term.
+     * @param targetLanguage The language the that the user prefers.
+     */
+    void forceTranslation(String sourceLanguage, String targetLanguage) {
+        mIsTranslationForced = true;
+        if (mLowPriorityUri != null) {
+            mLowPriorityUri = makeTranslateUri(mLowPriorityUri, sourceLanguage, targetLanguage);
+        }
+        mNormalPriorityUri = makeTranslateUri(mNormalPriorityUri, sourceLanguage, targetLanguage);
+    }
+
+    /**
+     * @return Whether translation was forced for this request.
+     */
+    @VisibleForTesting
+    boolean isTranslationForced() {
+        return mIsTranslationForced;
+    }
+
+    /**
      * Uses TemplateUrlService to generate the url for the given query
      * {@link String} for {@code query} with the contextual search version param set.
      * @param query The search term to use as the main query in the returned search url.
      * @param alternateTerm The alternate search term to use as an alternate suggestion.
      * @param shouldPrefetch Whether the returned url should include a prefetch parameter.
-     * @return      A {@link String} that contains the url of the default search engine with
-     *              {@code query} and {@code alternateTerm} inserted as parameters and contextual
-     *              search and prefetch parameters conditionally set.
+     * @return A {@link Uri} that contains the url of the default search engine with
+     *         {@code query} and {@code alternateTerm} inserted as parameters and contextual
+     *         search and prefetch parameters conditionally set.
      */
     private Uri getUriTemplate(String query, @Nullable String alternateTerm,
             boolean shouldPrefetch) {
         return Uri.parse(TemplateUrlService.getInstance().getUrlForContextualSearchQuery(
                 query, alternateTerm, shouldPrefetch));
     }
+
+    /**
+     * @return a low-priority {@code Uri} from the given base {@code Uri}.
+     */
+    private Uri makeLowPriorityUri(Uri baseUri) {
+        return baseUri.buildUpon()
+                .path(GWS_LOW_PRIORITY_SEARCH_PATH)
+                .appendQueryParameter(
+                        GWS_SEARCH_NO_SUGGESTIONS_PARAM, GWS_SEARCH_NO_SUGGESTIONS_PARAM_VALUE)
+                .build();
+    }
+
+    /**
+     * Makes the given {@code Uri} into a similar Uri that triggers a Translate one-box.
+     * @param baseUri The base Uri to build off of.
+     * @param sourceLanguage The language of the original search term.
+     * @param targetLanguage The language the that the user prefers.
+     * @return A {@link Uri} that has additional parameters for Translate appropriately set.
+     */
+    private Uri makeTranslateUri(Uri baseUri, String sourceLanguage, String targetLanguage) {
+        // TODO(donnd): update to work for non-English.  See also getTranslateQuery.
+        if (!TextUtils.equals(targetLanguage, Locale.ENGLISH.getLanguage())) return baseUri;
+        Uri resultUri = baseUri;
+        if (!sourceLanguage.isEmpty() || !targetLanguage.isEmpty()) {
+            // We must replace the q= param, and there seems to be no good way other than clearing
+            // all the query params and adding them all back in, changing q=.
+            Uri.Builder builder = baseUri.buildUpon().clearQuery();
+            String query = null;
+            for (String param : baseUri.getQueryParameterNames()) {
+                String value = baseUri.getQueryParameter(param);
+                if (TextUtils.equals(param, GWS_QUERY_PARAM)) {
+                    query = value;
+                    value = getTranslateQuery();
+                }
+                builder.appendQueryParameter(param, value);
+            }
+            if (!sourceLanguage.isEmpty()) {
+                builder.appendQueryParameter(TLITE_SOURCE_LANGUAGE_PARAM, sourceLanguage);
+            }
+            if (!targetLanguage.isEmpty()) {
+                builder.appendQueryParameter(TLITE_TARGET_LANGUAGE_PARAM, targetLanguage);
+            }
+            builder.appendQueryParameter(TLITE_QUERY_PARAM, query);
+            resultUri = builder.build();
+        }
+        return resultUri;
+    }
+
+    /**
+     * TODO(donnd): This translate API is evolving.  Update this code!
+     * TODO(donnd): As of Oct 2015 this will only work on production GWS to translate into English.
+     */
+    private String getTranslateQuery() {
+        return "Translate";
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java
index aa1916d..2bf7caf3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java
@@ -162,6 +162,7 @@
             // Query the package manager to see if there's a registered handler that matches.
             Intent intent = new Intent(Intent.ACTION_VIEW);
             intent.setDataAndType(Uri.parse(downloadInfo.getUrl()), downloadInfo.getMimeType());
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             // If the intent is resolved to ourselves, we don't want to attempt to load the url
             // only to try and download it again.
             if (DownloadManagerService.openIntent(mContext, intent, false)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java
index 66da6e32..1b1e9190 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java
@@ -9,6 +9,7 @@
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.Browser;
 
@@ -104,48 +105,75 @@
                 createAddBookmarkCallback(bookmarkModel, snackbarManager, activity));
     }
 
+    private static void showSnackbarForAddingBookmark(final EnhancedBookmarksModel bookmarkModel,
+            final SnackbarManager snackbarManager, final Activity activity,
+            final BookmarkId bookmarkId, final int saveResult, boolean isStorageAlmostFull) {
+        SnackbarController snackbarController = null;
+        int messageId;
+        int buttonId = 0;
+
+        OfflinePageBridge offlinePageBridge = bookmarkModel.getOfflinePageBridge();
+        if (offlinePageBridge == null) {
+            messageId = R.string.enhanced_bookmark_page_saved;
+        } else if (saveResult == AddBookmarkCallback.SKIPPED) {
+            messageId = R.string.offline_pages_page_skipped;
+        } else if (isStorageAlmostFull) {
+            messageId = saveResult == AddBookmarkCallback.SAVED
+                    ? R.string.offline_pages_page_saved_storage_near_full
+                    : R.string.offline_pages_page_failed_to_save_storage_near_full;
+            // Show "Free up space" button.
+            buttonId = R.string.offline_pages_free_up_space_title;
+            snackbarController = createSnackbarControllerForFreeUpSpaceButton(
+                    bookmarkModel, snackbarManager, activity);
+        } else {
+            messageId = saveResult == AddBookmarkCallback.SAVED
+                    ? R.string.offline_pages_page_saved
+                    : R.string.offline_pages_page_failed_to_save;
+        }
+
+        // Show "Edit" button when "Free up space" button is not desired, regardless
+        // whether the offline page was saved successfuly, because a bookmark was
+        // created and user might want to edit title.
+        if (buttonId == 0) {
+            buttonId = R.string.enhanced_bookmark_item_edit;
+            snackbarController = createSnackbarControllerForEditButton(
+                    bookmarkModel, activity, bookmarkId);
+        }
+
+        snackbarManager.showSnackbar(
+                Snackbar.make(activity.getString(messageId), snackbarController)
+                        .setAction(activity.getString(buttonId), null)
+                        .setSingleLine(false));
+    }
+
     private static AddBookmarkCallback createAddBookmarkCallback(
             final EnhancedBookmarksModel bookmarkModel, final SnackbarManager snackbarManager,
             final Activity activity) {
         return new AddBookmarkCallback() {
             @Override
-            public void onBookmarkAdded(BookmarkId bookmarkId, int saveResult) {
-                SnackbarController snackbarController = null;
-                int messageId;
-                int buttonId = 0;
-
-                OfflinePageBridge offlinePageBridge = bookmarkModel.getOfflinePageBridge();
-                if (offlinePageBridge == null) {
-                    messageId = R.string.enhanced_bookmark_page_saved;
-                } else if (saveResult == AddBookmarkCallback.SKIPPED) {
-                    messageId = R.string.offline_pages_page_skipped;
-                } else if (OfflinePageUtils.isStorageAlmostFull()) {
-                    messageId = saveResult == AddBookmarkCallback.SAVED
-                            ? R.string.offline_pages_page_saved_storage_near_full
-                            : R.string.offline_pages_page_failed_to_save_storage_near_full;
-                    // Show "Free up space" button.
-                    buttonId = R.string.offline_pages_free_up_space_title;
-                    snackbarController = createSnackbarControllerForFreeUpSpaceButton(
-                            bookmarkModel, snackbarManager, activity);
-                } else {
-                    messageId = saveResult == AddBookmarkCallback.SAVED
-                            ? R.string.offline_pages_page_saved
-                            : R.string.offline_pages_page_failed_to_save;
+            public void onBookmarkAdded(final BookmarkId bookmarkId, final int saveResult) {
+                // Shows the snackbar right away when offline pages feature is not enabled since
+                // there is no need to wait to get the storage info.
+                if (bookmarkModel.getOfflinePageBridge() == null) {
+                    showSnackbarForAddingBookmark(bookmarkModel, snackbarManager, activity,
+                                bookmarkId, saveResult, false);
+                    return;
                 }
 
-                // Show "Edit" button when "Free up space" button is not desired, regardless whether
-                // the offline page was saved successfuly, because a bookmark was created and user
-                // might want to edit title.
-                if (buttonId == 0) {
-                    buttonId = R.string.enhanced_bookmark_item_edit;
-                    snackbarController = createSnackbarControllerForEditButton(
-                            bookmarkModel, activity, bookmarkId);
-                }
+                // Gets the storage info asynchronously which is needed to produce the message for
+                // the snackbar.
+                new AsyncTask<Void, Void, Boolean>() {
+                    @Override
+                    protected Boolean doInBackground(Void... params) {
+                        return OfflinePageUtils.isStorageAlmostFull();
+                    }
 
-                snackbarManager.showSnackbar(
-                        Snackbar.make(activity.getString(messageId), snackbarController)
-                                .setAction(activity.getString(buttonId), null)
-                                .setSingleLine(false));
+                    @Override
+                    protected void onPostExecute(Boolean isStorageAlmostFull) {
+                        showSnackbarForAddingBookmark(bookmarkModel, snackbarManager, activity,
+                                bookmarkId, saveResult, isStorageAlmostFull);
+                    }
+                }.execute();
             }
         };
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
index 5c1888530c..360c6c2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -14,7 +14,6 @@
 import android.util.Log;
 
 import org.chromium.base.ApplicationStatus;
-import org.chromium.base.FieldTrialList;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.library_loader.ProcessInitException;
 import org.chromium.base.metrics.RecordHistogram;
@@ -48,8 +47,9 @@
     public static final String COMING_FROM_CHROME_ICON = "ComingFromChromeIcon";
     public static final String USE_FRE_FLOW_SEQUENCER = "UseFreFlowSequencer";
 
-    public static final String SHOW_WELCOME_PAGE = "ShowWelcome";
-    public static final String SHOW_SIGNIN_PAGE = "ShowSignIn";
+    static final String SHOW_WELCOME_PAGE = "ShowWelcome";
+    static final String SHOW_SIGNIN_PAGE = "ShowSignIn";
+    static final String SHOW_DATA_REDUCTION_PAGE = "ShowDataReduction";
 
     // Outcoming results:
     public static final String RESULT_CLOSE_APP = "Close App";
@@ -102,7 +102,7 @@
         if (mShowWelcomePage) mPages.add(pageOf(ToSAndUMAFirstRunFragment.class));
 
         // An optional Data Saver page.
-        if (FieldTrialList.findFullName("DataReductionProxyFREPromo").startsWith("Enabled")) {
+        if (mFreProperties.getBoolean(SHOW_DATA_REDUCTION_PAGE)) {
             mPages.add(pageOf(DataReductionProxyFirstRunFragment.class));
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index 5208c082..843d9c1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -12,6 +12,7 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.CommandLine;
+import org.chromium.base.FieldTrialList;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ChromeVersionInfo;
@@ -111,6 +112,10 @@
         return PrefServiceBridge.getInstance().isFirstRunEulaAccepted();
     }
 
+    protected boolean shouldShowDataReductionPage() {
+        return FieldTrialList.findFullName("DataReductionProxyFREPromo").startsWith("Enabled");
+    }
+
     @VisibleForTesting
     protected void enableCrashUpload() {
         PrivacyPreferencesManager.getInstance(mActivity.getApplicationContext())
@@ -176,6 +181,9 @@
 
         freProperties.putBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT, hasChildAccount);
 
+        freProperties.putBoolean(FirstRunActivity.SHOW_DATA_REDUCTION_PAGE,
+                shouldShowDataReductionPage());
+
         onFlowIsKnown(freProperties);
         if (hasChildAccount || forceEduSignIn) {
             // Child and Edu forced signins are processed independently.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarControlLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarControlLayout.java
new file mode 100644
index 0000000..f90defe
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarControlLayout.java
@@ -0,0 +1,66 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.infobar;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import org.chromium.chrome.R;
+
+/**
+ * Lays out controls for InfoBars that require more than the standard pair of OK/CANCEL buttons.
+ *
+ * This class works with the {@link InfoBarLayout} to define a standard set of controls with
+ * standardized spacings and text styling that gets laid out in grid form: https://crbug.com/543205
+ *
+ * TODO(dfalcantara): Implement the measurement and layout algorithms.
+ */
+public class InfoBarControlLayout extends FrameLayout {
+
+    public InfoBarControlLayout(Context context) {
+        super(context);
+    }
+
+    /**
+     * Adds a toggle switch to the layout.
+     *
+     * -------------------------------------------------
+     * | ICON | MESSAGE                       | TOGGLE |
+     * -------------------------------------------------
+     * If an icon is not provided, the ImageView that would normally show it is hidden.
+     *
+     * @param iconResourceId ID of the drawable to use for the icon, or 0 to hide the ImageView.
+     * @param toggleMessage  Message to display for the toggle.
+     * @param toggleId       ID to use for the toggle.
+     * @param isChecked      Whether the toggle should start off checked.
+     */
+    public LinearLayout addSwitch(
+            int iconResourceId, CharSequence toggleMessage, int toggleId, boolean isChecked) {
+        LinearLayout switchLayout = (LinearLayout) LayoutInflater.from(getContext()).inflate(
+                R.layout.infobar_control_toggle, this, false);
+        addView(switchLayout);
+
+        ImageView iconView = (ImageView) switchLayout.findViewById(R.id.control_toggle_icon);
+        if (iconResourceId == 0) {
+            removeView(iconView);
+        } else {
+            iconView.setImageResource(iconResourceId);
+        }
+
+        TextView messageView = (TextView) switchLayout.findViewById(R.id.control_toggle_message);
+        messageView.setText(toggleMessage);
+
+        Switch switchView = (Switch) switchLayout.findViewById(R.id.control_toggle_switch);
+        switchView.setId(toggleId);
+        switchView.setChecked(isChecked);
+
+        return switchLayout;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateAlwaysPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateAlwaysPanel.java
index e902387..506211f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateAlwaysPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateAlwaysPanel.java
@@ -1,6 +1,7 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// Copyright 2015 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+
 package org.chromium.chrome.browser.infobar;
 
 import android.content.Context;
@@ -26,8 +27,7 @@
                 R.string.translate_infobar_translation_done, mOptions.targetLanguage()));
 
         if (!mOptions.triggeredFromMenu()) {
-            TranslateCheckBox checkBox = new TranslateCheckBox(context, mOptions, mListener);
-            layout.setCustomContent(checkBox);
+            layout.setCustomContent(createAlwaysToggle(context, mOptions));
         }
 
         layout.setButtons(context.getString(R.string.translate_button_done),
@@ -42,4 +42,16 @@
             mListener.onPanelClosed(ActionType.TRANSLATE_SHOW_ORIGINAL);
         }
     }
+
+    /**
+     * Creates a toggle that shows the current status of the "Always translate <language>" option.
+     */
+    static InfoBarControlLayout createAlwaysToggle(Context context, TranslateOptions options) {
+        InfoBarControlLayout controlLayout = new InfoBarControlLayout(context);
+        controlLayout.addSwitch(-1,
+                context.getString(R.string.translate_always_text, options.sourceLanguage()),
+                R.id.translate_infobar_always_toggle,
+                options.alwaysTranslateLanguageState());
+        return controlLayout;
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCheckBox.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCheckBox.java
deleted file mode 100644
index 4d247db..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateCheckBox.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.chrome.browser.infobar;
-
-import android.content.Context;
-import android.support.v7.widget.AppCompatCheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.chrome.R;
-
-/**
- * A check box used to determine if a page should always be translated.
- */
-public class TranslateCheckBox extends AppCompatCheckBox implements OnCheckedChangeListener {
-    private static final int TEXT_SIZE_SP = 13;
-
-    private final SubPanelListener mListener;
-    private final TranslateOptions mOptions;
-
-    public TranslateCheckBox(Context context, TranslateOptions options, SubPanelListener listener) {
-        super(context);
-        mOptions = options;
-        mListener = listener;
-
-        setId(R.id.infobar_extra_check);
-        setText(context.getString(R.string.translate_always_text, mOptions.sourceLanguage()));
-        setTextColor(
-                ApiCompatibilityUtils.getColor(context.getResources(), R.color.default_text_color));
-        setTextSize(TEXT_SIZE_SP);
-        setChecked(mOptions.alwaysTranslateLanguageState());
-        setOnCheckedChangeListener(this);
-    }
-
-    @Override
-    public void onCheckedChanged(CompoundButton view, boolean isChecked) {
-        mOptions.toggleAlwaysTranslateLanguageState(isChecked);
-        mListener.onPanelClosed(ActionType.NONE);
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateInfoBar.java
index 7e4f68b..5d462e4d8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateInfoBar.java
@@ -11,7 +11,9 @@
 import android.text.TextUtils;
 import android.text.style.ClickableSpan;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.CheckBox;
+import android.widget.Switch;
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.chrome.R;
@@ -189,9 +191,9 @@
         if (getInfoBarType() == AFTER_TRANSLATE_INFOBAR
                 && !needsAlwaysPanel()
                 && !mOptions.triggeredFromMenu()) {
-            // Long always translate version
-            TranslateCheckBox checkBox = new TranslateCheckBox(context, mOptions, this);
-            layout.setCustomContent(checkBox);
+            // Fully expanded version of the "Always Translate" InfoBar.
+            ViewGroup subLayout = TranslateAlwaysPanel.createAlwaysToggle(context, mOptions);
+            layout.setCustomContent(subLayout);
         }
     }
 
@@ -230,6 +232,13 @@
     public void onOptionsChanged() {
         if (mNativeTranslateInfoBarPtr == 0) return;
 
+        // Handle the "Always Translate" checkbox.
+        if (getInfoBarType() == AFTER_TRANSLATE_INFOBAR) {
+            Switch alwaysSwitch =
+                    (Switch) getContentWrapper().findViewById(R.id.translate_infobar_always_toggle);
+            mOptions.toggleAlwaysTranslateLanguageState(alwaysSwitch.isChecked());
+        }
+
         if (mOptions.optionsChanged()) {
             nativeApplyTranslateOptions(mNativeTranslateInfoBarPtr, mOptions.sourceLanguageIndex(),
                     mOptions.targetLanguageIndex(), mOptions.alwaysTranslateLanguageState(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
index 7a94603..5792259 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.offlinepages;
 
 import android.content.pm.PackageManager;
+import android.os.AsyncTask;
 
 import org.chromium.base.ObserverList;
 import org.chromium.base.ThreadUtils;
@@ -93,13 +94,19 @@
         public void offlinePageDeleted(BookmarkId bookmarkId) {}
     }
 
-    private static int getFreeSpacePercentage() {
-        return (int) (1.0 * OfflinePageUtils.getFreeSpaceInBytes()
-                / OfflinePageUtils.getTotalSpaceInBytes() * 100);
-    }
-
-    private static int getFreeSpaceMB() {
-        return (int) (OfflinePageUtils.getFreeSpaceInBytes() / (1024 * 1024));
+    private static void recordFreeSpaceHistograms(
+            final String percentageName, final String bytesName) {
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                int percentage = (int) (1.0 * OfflinePageUtils.getFreeSpaceInBytes()
+                        / OfflinePageUtils.getTotalSpaceInBytes() * 100);
+                RecordHistogram.recordEnumeratedHistogram(percentageName, percentage, 101);
+                int bytesInMB = (int) (OfflinePageUtils.getFreeSpaceInBytes() / (1024 * 1024));
+                RecordHistogram.recordCustomCountHistogram(bytesName, bytesInMB, 1, 500000, 50);
+                return null;
+            }
+        }.execute();
     }
 
     /**
@@ -195,23 +202,18 @@
     public void savePage(final WebContents webContents, final BookmarkId bookmarkId,
             WindowAndroid windowAndroid, final SavePageCallback callback) {
         assert mIsNativeOfflinePageModelLoaded;
-        RecordHistogram.recordEnumeratedHistogram(
-                "OfflinePages.SavePage.FreeSpacePercentage", getFreeSpacePercentage(), 101);
-        RecordHistogram.recordCustomCountHistogram(
-                "OfflinePages.SavePage.FreeSpaceMB", getFreeSpaceMB(), 1, 500000, 50);
 
         if (windowAndroid == null) {
             callback.onSavePageDone(SavePageResult.CONTENT_UNAVAILABLE, webContents.getUrl());
         } else if (OfflinePageUtils.hasFileAccessPermission(windowAndroid)) {
-            nativeSavePage(mNativeOfflinePageBridge, callback, webContents, bookmarkId.getId());
+            doSavePage(callback, webContents, bookmarkId);
         } else {
             PermissionCallback permissionCallback = new PermissionCallback() {
                 @Override
                 public void onRequestPermissionsResult(String[] permission, int[] grantResults) {
                     if (grantResults.length > 0
                             && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-                        nativeSavePage(mNativeOfflinePageBridge, callback, webContents,
-                                bookmarkId.getId());
+                        doSavePage(callback, webContents, bookmarkId);
                     } else {
                         callback.onSavePageDone(SavePageResult.CANCELLED, webContents.getUrl());
                     }
@@ -222,6 +224,13 @@
         }
     }
 
+    private void doSavePage(SavePageCallback callback, WebContents webContents,
+            BookmarkId bookmarkId) {
+        recordFreeSpaceHistograms(
+                "OfflinePages.SavePage.FreeSpacePercentage", "OfflinePages.SavePage.FreeSpaceMB");
+        nativeSavePage(mNativeOfflinePageBridge, callback, webContents, bookmarkId.getId());
+    }
+
     /**
      * Marks that an offline page related to a specified bookmark has been accessed.
      *
@@ -245,20 +254,16 @@
             final DeletePageCallback callback) {
         assert mIsNativeOfflinePageModelLoaded;
         assert windowAndroid != null;
-        RecordHistogram.recordEnumeratedHistogram(
-                "OfflinePages.DeletePage.FreeSpacePercentage", getFreeSpacePercentage(), 101);
-        RecordHistogram.recordCustomCountHistogram(
-                "OfflinePages.DeletePage.FreeSpaceMB", getFreeSpaceMB(), 1, 500000, 50);
 
         if (OfflinePageUtils.hasFileAccessPermission(windowAndroid)) {
-            nativeDeletePage(mNativeOfflinePageBridge, callback, bookmarkId.getId());
+            doDeletePage(callback, bookmarkId);
         } else {
             PermissionCallback permissionCallback = new PermissionCallback() {
                 @Override
                 public void onRequestPermissionsResult(String[] permission, int[] grantResults) {
                     if (grantResults.length > 0
                             && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-                        nativeDeletePage(mNativeOfflinePageBridge, callback, bookmarkId.getId());
+                        doDeletePage(callback, bookmarkId);
                     } else {
                         callback.onDeletePageDone(DeletePageResult.DEVICE_FAILURE);
                     }
@@ -269,6 +274,12 @@
         }
     }
 
+    private void doDeletePage(DeletePageCallback callback, BookmarkId bookmarkId) {
+        recordFreeSpaceHistograms("OfflinePages.DeletePage.FreeSpacePercentage",
+                "OfflinePages.DeletePage.FreeSpaceMB");
+        nativeDeletePage(mNativeOfflinePageBridge, callback, bookmarkId.getId());
+    }
+
     /**
      * Deletes offline pages based on the list of provided bookamrk IDs. Calls the callback
      * when operation is complete. Requires that the model is already loaded.
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_da.xtb b/chrome/android/java/strings/translations/android_chrome_strings_da.xtb
index b727467..30d2e4d 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_da.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_da.xtb
@@ -72,7 +72,7 @@
 <translation id="2077711166702792587">Se dine faner med andre nye apps på oversigtsskærmen på din telefon.</translation>
 <translation id="2079545284768500474">Fortryd</translation>
 <translation id="2082238445998314030">Resultat <ph name="RESULT_NUMBER" /> af <ph name="TOTAL_RESULTS" /></translation>
-<translation id="2095887075102408547">Når denne funktion er aktiveret, anvender Chrome Googles servere til at komprimere de sider, du besøger, før de downloades. Google optimerer og viser ikke sider, der besøges via private forbindelser (HTTPS) eller inkognitofaner.</translation>
+<translation id="2095887075102408547">Når denne funktion er aktiveret, anvender Chrome Googles servere til at komprimere de sider, du besøger, før de downloades. Google optimerer og ser ikke sider, der besøges via private forbindelser (HTTPS) eller inkognitofaner.</translation>
 <translation id="2100273922101894616">Automatisk login</translation>
 <translation id="2126426811489709554">Leveret af Chrome</translation>
 <translation id="213279576345780926">Lukkede <ph name="TAB_TITLE" /></translation>
@@ -148,7 +148,7 @@
 <translation id="3254409185687681395">Tilføj denne side som bogmærke</translation>
 <translation id="326254929494722411">Du har endnu ikke oprettet en Google-konto på denne enhed</translation>
 <translation id="3269093882174072735">Indlæs billede</translation>
-<translation id="3278850099957560514">Brug færre penge på data ved at bruge Google til at optimere de sider, du besøger. Google optimerer og viser ikke sider, der besøges via private forbindelser (HTTPS) eller inkognitofaner.</translation>
+<translation id="3278850099957560514">Brug færre penge på data ved at bruge Google til at optimere de sider, du besøger. Google optimerer og ser ikke sider, der besøges via private forbindelser (HTTPS) eller inkognitofaner.</translation>
 <translation id="3282568296779691940">Log ind på Chrome</translation>
 <translation id="3287852534598822456">Bogmærket eksisterer ikke længere. Opdater.</translation>
 <translation id="3303414029551471755">Vil du fortsætte og downloade indholdet?</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb b/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb
index 1bfbfdba..dff9db9 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb
@@ -463,7 +463,7 @@
 <translation id="7765158879357617694">Mover</translation>
 <translation id="7767746238359002192">Visita la página para guardarla sin conexión</translation>
 <translation id="7772032839648071052">Confirmar frase de contraseña</translation>
-<translation id="7784213092572143271">Página guardada</translation>
+<translation id="7784213092572143271">Se guardó la página</translation>
 <translation id="7788788617745289808">Chrome necesita acceso a la cámara para compartirla con este sitio.</translation>
 <translation id="7791543448312431591">Agregar</translation>
 <translation id="780301667611848630">No, gracias</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_id.xtb b/chrome/android/java/strings/translations/android_chrome_strings_id.xtb
index 7c309d8..e66f93ae 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_id.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_id.xtb
@@ -148,7 +148,7 @@
 <translation id="3254409185687681395">Bookmark laman ini</translation>
 <translation id="326254929494722411">Anda belum menyiapkan Akun Google di perangkat ini</translation>
 <translation id="3269093882174072735">Muat gambar</translation>
-<translation id="3278850099957560514">Hemat data dengan menggunakan Google guna mengoptimalkan laman yang Anda kunjungi. Laman yang diakses menggunakan sambungan pribadi (HTTPS) atau tab Penyamaran tidak akan dioptimalkan maupun dilihat oleh Google.</translation>
+<translation id="3278850099957560514">Hemat data dengan menggunakan Google untuk mengoptimalkan laman yang Anda kunjungi. Laman yang diakses menggunakan sambungan pribadi (HTTPS) atau tab Penyamaran tidak akan dioptimalkan maupun dilihat oleh Google.</translation>
 <translation id="3282568296779691940">Masuk ke Chrome</translation>
 <translation id="3287852534598822456">Bookmark sudah tidak ada. Segarkan.</translation>
 <translation id="3303414029551471755">Lanjutkan untuk mengunduh konten?</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb b/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb
index b89d61e..38e2302 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb
@@ -72,7 +72,7 @@
 <translation id="2077711166702792587">הצג את הכרטיסיות עם האפליקציות האחרונות שבהן השתמשת במסך הסקירה של הטלפון.</translation>
 <translation id="2079545284768500474">בטל</translation>
 <translation id="2082238445998314030">תוצאה <ph name="RESULT_NUMBER" /> מתוך <ph name="TOTAL_RESULTS" /></translation>
-<translation id="2095887075102408547">‏כשהתכונה הזו פועלת, Chrome ישתמש בשרתי Google כדי לדחוס דפים שבהם אתה מבקר לפני שהוא מוריד אותם. Google לא תראה או תבצע אופטימיזציה של דפים שהגישה אליהם בוצעה דרך קישורים פרטיים (HTTPS) או בכרטיסיות גלישה בסתר.</translation>
+<translation id="2095887075102408547">‏כשהתכונה הזו פועלת, Chrome ישתמש בשרתי Google כדי לדחוס דפים שבהם אתה מבקר לפני הורדתם. Google לא תראה דפים שהגישה אליהם בוצעה בחיבור פרטי (HTTPS) או בכרטיסיות גלישה בסתר', וגם לא תבצע אופטימיזציה שלהם.</translation>
 <translation id="2100273922101894616">כניסה אוטומטית</translation>
 <translation id="2126426811489709554">‏מבוסס על Chrome</translation>
 <translation id="213279576345780926"><ph name="TAB_TITLE" /> נסגר</translation>
@@ -148,7 +148,7 @@
 <translation id="3254409185687681395">הוסף את הדף לסימניות</translation>
 <translation id="326254929494722411">‏עדיין לא הגדרת חשבון Google במכשיר הזה</translation>
 <translation id="3269093882174072735">טען תמונה</translation>
-<translation id="3278850099957560514">‏צמצם את ההוצאה על שימוש בנתונים על ידי שימוש ב-Google כדי לבצע אופטימיזציה לדפים שבהם אתה מבקר. Google לא תראה או תבצע אופטימיזציה של דפים שהגישה אליהם בוצעה דרך קישורים פרטיים (HTTPS) או בכרטיסיות גלישה בסתר.</translation>
+<translation id="3278850099957560514">‏צמצם את ההוצאה על תקשורת נתונים על ידי שימוש באופטימיזציה של Google לדפים שבהם אתה מבקר. Google לא תראה דפים שהגישה אליהם בוצעה בחיבור פרטי (HTTPS) או בכרטיסיות גלישה בסתר, וגם לא תבצע אופטימיזציה שלהם.</translation>
 <translation id="3282568296779691940">‏כניסה ל-Chrome</translation>
 <translation id="3287852534598822456">הסימנייה כבר לא קיימת. נדרש רענון.</translation>
 <translation id="3303414029551471755">האם להוריד את התוכן?</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_no.xtb b/chrome/android/java/strings/translations/android_chrome_strings_no.xtb
index 0d1390c3..1cea764 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_no.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_no.xtb
@@ -82,7 +82,7 @@
 <translation id="2206488550163399966"><ph name="APP_NAME" />, nettprogram. <ph name="APP_URL" /></translation>
 <translation id="2268044343513325586">Finstem</translation>
 <translation id="2315043854645842844">Operativsystemet har ikke støtte for sertifikatvalg på klientsiden.</translation>
-<translation id="2316129865977710310">Nei takk</translation>
+<translation id="2316129865977710310">Nei, takk</translation>
 <translation id="2321958826496381788">Dra glidebryteren til du kan lese dette uten problemer. Når du har dobbelttrykket på et avsnitt, bør teksten være minst like stor som dette.</translation>
 <translation id="2343328333327081434">Installerer …</translation>
 <translation id="2351097562818989364">Oversettelsesinnstillingene dine er tilbakestilt.</translation>
@@ -434,12 +434,12 @@
 <translation id="7363354739009474003">Laster inn <ph name="VIDEO_TITLE" /> ...</translation>
 <translation id="7366340029385295517">Caster til <ph name="SCREEN_NAME" /></translation>
 <translation id="7375125077091615385">Type:</translation>
-<translation id="7378627244592794276">Nei takk</translation>
+<translation id="7378627244592794276">Nei, takk</translation>
 <translation id="7400418766976504921">Nettadresse</translation>
 <translation id="7400448254438078120">Videoen kan ikke castes på grunn av restriksjoner på nettstedet.</translation>
 <translation id="7423098979219808738">Spør først.</translation>
 <translation id="7437998757836447326">Logg av Chrome</translation>
-<translation id="7473891865547856676">Nei takk</translation>
+<translation id="7473891865547856676">Nei, takk</translation>
 <translation id="748127970106343339">Bekreft sletting av enhetslegitimasjon</translation>
 <translation id="7493994139787901920"><ph name="VERSION" /> (oppdatert <ph name="TIME_SINCE_UPDATE" />)</translation>
 <translation id="7498271377022651285">Vent litt</translation>
@@ -465,7 +465,7 @@
 <translation id="7784213092572143271">Siden er lagret</translation>
 <translation id="7788788617745289808">Chrome må ha tilgang til kameraet for å kunne dele det med dette nettstedet.</translation>
 <translation id="7791543448312431591">Legg til</translation>
-<translation id="780301667611848630">Nei takk</translation>
+<translation id="780301667611848630">Nei, takk</translation>
 <translation id="7811044698839470685">De krypterte dataene dine kan ikke leses av andre enn de som har passordfrasen din. Denne frasen verken sendes til eller lagres av Google, og hvis du glemmer den, må du tilbakestille synkroniseringen.</translation>
 <translation id="7829298379596169484">Åpner lydinngang</translation>
 <translation id="7846076177841592234">Opphev valget</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb
index eeb6d2b..23b03d2 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb
@@ -148,7 +148,7 @@
 <translation id="3254409185687681395">Marcați această pagină</translation>
 <translation id="326254929494722411">Nu ai configurat încă un Cont Google pe acest dispozitiv</translation>
 <translation id="3269093882174072735">Încarcă imaginea</translation>
-<translation id="3278850099957560514">Reduce volumul de date transferat optimizând cu Google paginile accesate. Paginile accesate folosind conexiuni private (HTTPS) sau în file incognito nu vor fi optimizate sau detectate de Google.</translation>
+<translation id="3278850099957560514">Cheltuiește mai puțin pe date mobile folosind Google pentru a optimiza paginile accesate. Paginile accesate folosind conexiuni private (HTTPS) sau în file incognito nu vor fi optimizate sau detectate de Google.</translation>
 <translation id="3282568296779691940">Conectați-vă la Chrome</translation>
 <translation id="3287852534598822456">Marcajul nu mai există. Actualizează.</translation>
 <translation id="3303414029551471755">Continui pentru descărcarea conținutului?</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb
index 0a5966d..b29f450 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb
@@ -148,7 +148,7 @@
 <translation id="3254409185687681395">Zaznamujte to stran</translation>
 <translation id="326254929494722411">V tej napravi še niste nastavili Google Računa</translation>
 <translation id="3269093882174072735">Naloži sliko</translation>
-<translation id="3278850099957560514">Porabite manj za prenos podatkov z uporabo Googla za optimiziranje strani, ki jih obiščete. Strani, do katerih dostopate prek zasebnih povezav (HTTPS) ali jih odprete na zavihkih brez beleženja zgodovine, Google ne vidi in jih ne optimizira.</translation>
+<translation id="3278850099957560514">Za optimiziranje strani, ki jih obiščete, uporabite Google in porabite manj za prenos podatkov. Strani, do katerih dostopate prek zasebnih povezav (HTTPS) ali jih odprete na zavihkih brez beleženja zgodovine, Google ne vidi in jih ne optimizira.</translation>
 <translation id="3282568296779691940">Prijava v Google Chrome</translation>
 <translation id="3287852534598822456">Zaznamek ne obstaja več. Osvežite.</translation>
 <translation id="3303414029551471755">Ali želite prenesti vsebino?</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb
index 23ee32df..0d846e72 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb
@@ -462,10 +462,10 @@
 <translation id="7765158879357617694">Sogeza</translation>
 <translation id="7767746238359002192">Tembelea ukurasa ili uhifadhi nje ya mtandao</translation>
 <translation id="7772032839648071052">Thibitisha kaulisiri</translation>
-<translation id="7784213092572143271">Ukurasa ulihifadhiwa</translation>
+<translation id="7784213092572143271">Ukurasa umehifadhiwa</translation>
 <translation id="7788788617745289808">Chrome inahitaji idhini ya kufikia kamera ili iishiriki na tovuti hii.</translation>
 <translation id="7791543448312431591">Ongeza</translation>
-<translation id="780301667611848630">La, asante</translation>
+<translation id="780301667611848630">Sitaki</translation>
 <translation id="7811044698839470685">Ni mtu aliye na kaulisiri yako pekee ndiye anayeweza kusoma data yako iliyosimbwa kwa njia fiche. Kaulisiri haitumwi kwa au kuhifadhiwa na Google. Ukisahau kaulisiri yako, utahitaji kuweka upya usawazishaji.</translation>
 <translation id="7829298379596169484">Inafikia vifaa vya kuingiza sauti</translation>
 <translation id="7846076177841592234">Ghairi uchaguzi</translation>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java
index 2cbed01..1538001 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java
@@ -141,6 +141,8 @@
         private final boolean mDoPreventPreload;
         private final int mStartAdjust;
         private final int mEndAdjust;
+        private final String mContextLanguage;
+
 
         boolean mDidStartResolution;
         boolean mDidFinishResolution;
@@ -154,11 +156,13 @@
          * @param alternateTerm         The alternate text.
          * @param doPreventPreload      Whether search preload should be prevented.
          * @param startAdjust           The start adjustment of the selection.
-         * @param endAdjudst            The end adjustment of the selection.
+         * @param endAdjust             The end adjustment of the selection.
+         * @param contextLanguage       The language of the context determined by the server.
          */
         FakeTapSearch(String nodeId, boolean isNetworkUnavailable, int responseCode,
                       String searchTerm, String displayText, String alternateTerm,
-                      boolean doPreventPreload, int startAdjust, int endAdjudst) {
+                      boolean doPreventPreload, int startAdjust, int endAdjust,
+                      String contextLanguage) {
             super(nodeId);
 
             mIsNetworkUnavailable = isNetworkUnavailable;
@@ -168,7 +172,8 @@
             mAlternateTerm = alternateTerm;
             mDoPreventPreload = doPreventPreload;
             mStartAdjust = startAdjust;
-            mEndAdjust = endAdjudst;
+            mEndAdjust = endAdjust;
+            mContextLanguage = contextLanguage;
         }
 
         @Override
@@ -226,7 +231,7 @@
         /**
          * Simulates a Search Term Resolution.
          */
-        private void simulateSearchTermResolution() throws InterruptedException, TimeoutException {
+        private void simulateSearchTermResolution() {
             mManagerTest.runOnMainSync(getRunnable());
         }
 
@@ -240,7 +245,8 @@
                     if (!mDidFinishResolution) {
                         handleSearchTermResolutionResponse(
                                 mIsNetworkUnavailable, mResponseCode, mSearchTerm, mDisplayText,
-                                mAlternateTerm, mDoPreventPreload, mStartAdjust, mEndAdjust);
+                                mAlternateTerm, mDoPreventPreload, mStartAdjust, mEndAdjust,
+                                mContextLanguage);
 
                         mActiveFakeTapSearch = null;
                         mDidFinishResolution = true;
@@ -386,7 +392,7 @@
     }
 
     /**
-     * @return
+     * @return Whether onShow() was ever called for the current {@code ContentViewCore}.
      */
     @VisibleForTesting
     boolean didEverCallContentViewCoreOnShow() {
@@ -433,10 +439,10 @@
     @Override
     public void handleSearchTermResolutionResponse(boolean isNetworkUnavailable, int responseCode,
             String searchTerm, String displayText, String alternateTerm, boolean doPreventPreload,
-            int selectionStartAdjust, int selectionEndAdjust) {
+            int selectionStartAdjust, int selectionEndAdjust, String contextLanguage) {
         mBaseManager.handleSearchTermResolutionResponse(isNetworkUnavailable, responseCode,
                 searchTerm, displayText, alternateTerm, doPreventPreload, selectionStartAdjust,
-                selectionEndAdjust);
+                selectionEndAdjust, contextLanguage);
     }
 
     @Override
@@ -469,11 +475,13 @@
         registerFakeLongPressSearch(new FakeLongPressSearch("resolution", "Resolution"));
 
         registerFakeTapSearch(new FakeTapSearch("search", false, 200,
-                "Search", "Search", "alternate-term", false, 0, 0));
+                "Search", "Search", "alternate-term", false, 0, 0, ""));
         registerFakeTapSearch(new FakeTapSearch("term", false, 200,
-                "Term", "Term", "alternate-term", false, 0, 0));
+                "Term", "Term", "alternate-term", false, 0, 0, ""));
         registerFakeTapSearch(new FakeTapSearch("resolution", false, 200,
-                "Resolution", "Resolution", "alternate-term", false, 0, 0));
+                "Resolution", "Resolution", "alternate-term", false, 0, 0, ""));
+        registerFakeTapSearch(new FakeTapSearch("german", false, 200,
+                "Deutsche", "Deutsche", "alternate-term", false, 0, 0, "de"));
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index 81a7bba..16dc455 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -268,10 +268,12 @@
         private final boolean mDoPreventPreload;
         private final int mStartAdjust;
         private final int mEndAdjust;
+        private final String mContextLanguage;
 
         public FakeResponseOnMainThread(boolean isNetworkUnavailable, int responseCode,
                                         String searchTerm, String displayText, String alternateTerm,
-                                        boolean doPreventPreload, int startAdjust, int endAdjudst) {
+                                        boolean doPreventPreload, int startAdjust, int endAdjudst,
+                                        String contextLanguage) {
             mIsNetworkUnavailable = isNetworkUnavailable;
             mResponseCode = responseCode;
             mSearchTerm = searchTerm;
@@ -280,13 +282,14 @@
             mDoPreventPreload = doPreventPreload;
             mStartAdjust = startAdjust;
             mEndAdjust = endAdjudst;
+            mContextLanguage = contextLanguage;
         }
 
         @Override
         public void run() {
-            mFakeServer.handleSearchTermResolutionResponse(
-                    mIsNetworkUnavailable, mResponseCode, mSearchTerm, mDisplayText,
-                    mAlternateTerm, mDoPreventPreload, mStartAdjust, mEndAdjust);
+            mFakeServer.handleSearchTermResolutionResponse(mIsNetworkUnavailable, mResponseCode,
+                    mSearchTerm, mDisplayText, mAlternateTerm, mDoPreventPreload, mStartAdjust,
+                    mEndAdjust, mContextLanguage);
         }
     }
 
@@ -297,20 +300,20 @@
     private void fakeResponse(boolean isNetworkUnavailable, int responseCode,
             String searchTerm, String displayText, String alternateTerm, boolean doPreventPreload) {
         fakeResponse(isNetworkUnavailable, responseCode, searchTerm, displayText, alternateTerm,
-                doPreventPreload, 0, 0);
+                doPreventPreload, 0, 0, "");
     }
 
     /**
      * Fakes a server response with the parameters given.
      * {@See ContextualSearchManager#handleSearchTermResolutionResponse}.
      */
-    private void fakeResponse(boolean isNetworkUnavailable, int responseCode,
-            String searchTerm, String displayText, String alternateTerm, boolean doPreventPreload,
-            int startAdjust, int endAdjust) {
+    private void fakeResponse(boolean isNetworkUnavailable, int responseCode, String searchTerm,
+            String displayText, String alternateTerm, boolean doPreventPreload, int startAdjust,
+            int endAdjust, String contextLanguage) {
         if (mFakeServer.getSearchTermRequested() != null) {
-            getInstrumentation().runOnMainSync(
-                    new FakeResponseOnMainThread(isNetworkUnavailable, responseCode, searchTerm,
-                            displayText, alternateTerm, doPreventPreload, startAdjust, endAdjust));
+            getInstrumentation().runOnMainSync(new FakeResponseOnMainThread(isNetworkUnavailable,
+                    responseCode, searchTerm, displayText, alternateTerm, doPreventPreload,
+                    startAdjust, endAdjust, contextLanguage));
         }
     }
 
@@ -449,10 +452,18 @@
      */
     private void assertLoadedSearchTermMatches(String searchTerm) {
         boolean doesMatch = false;
+        String message = "but there was no loaded URL!";
         if (mFakeServer != null) {
             doesMatch = mFakeServer.getLoadedUrl().contains("q=" + searchTerm);
+            // TODO(donnd): remove the following line once the Translate API is updated!
+            // The current Translate API requires a change to the query parameter so
+            // checking it for the search term does not work.  We plan to fix this very
+            // soon, and this workaround allows tests to work until then, but needs to be
+            // removed when we switch to the new API.  See crbug.com/413717.
+            doesMatch = doesMatch || mFakeServer.getLoadedUrl().contains("tlitetxt=" + searchTerm);
+            message = "in URL: " + mFakeServer.getLoadedUrl();
         }
-        assertTrue(doesMatch);
+        assertTrue("Expected to find searchTerm " + searchTerm + ", " + message, doesMatch);
     }
 
     private void assertContainsParameters(String searchTerm, String alternateTerm) {
@@ -1049,7 +1060,7 @@
      * @SmallTest
      * @Feature({"ContextualSearch"})
      */
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @FlakyTest
     public void testTapExpand() throws InterruptedException, TimeoutException {
         assertNoSearchesLoaded();
@@ -1237,6 +1248,7 @@
     /**
      * Tests that a Tap gesture followed by tapping a non-text character doesn't select.
      */
+    @DisabledTest // https://crbug.com/552107
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
@@ -1850,7 +1862,7 @@
      * @SmallTest
      * @Feature({"ContextualSearch"})
      */
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     @CommandLineFlags.Add({
             ContextualSearchFieldTrial.PROMO_ON_LIMITED_TAPS + "=true",
             ContextualSearchFieldTrial.TAP_TRIGGERED_PROMO_LIMIT + "=2"})
@@ -2194,7 +2206,7 @@
         waitForPanelToPeekAndAssert();
 
         fakeResponse(false, 200, "Intelligence", "United States Intelligence", "alternate-term",
-                false, -14, 0);
+                false, -14, 0, "");
         waitForSelectionToBe("United States Intelligence");
     }
 
@@ -2245,7 +2257,6 @@
     /**
      * Tests that tap followed by expand makes Content visible.
      */
-    @DisabledTest // https://crbug.com/551711
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
@@ -2267,7 +2278,6 @@
      * Tests that long press followed by expand creates Content and makes it visible.
      *
      */
-    @DisabledTest // https://crbug.com/551711
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
@@ -2290,10 +2300,9 @@
     /**
      * Tests swiping panel up and down after a tap search will only load the Content once.
      */
-    @DisabledTest // https://crbug.com/551711
     @SmallTest
     @Feature({"ContextualSearch"})
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testTapMultipleSwipeOnlyLoadsContentOnce()
             throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure Content is not visible.
@@ -2326,10 +2335,9 @@
     /**
      * Tests swiping panel up and down after a long press search will only load the Content once.
      */
-    @DisabledTest // https://crbug.com/551711
     @SmallTest
     @Feature({"ContextualSearch"})
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testLongPressMultipleSwipeOnlyLoadsContentOnce()
             throws InterruptedException, TimeoutException {
         // Simulate a long press and make sure no Content is created.
@@ -2404,7 +2412,7 @@
     @DisabledTest // https://crbug.com/551711
     @SmallTest
     @Feature({"ContextualSearch"})
-    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
     public void testChainedSearchLoadsCorrectSearchTerm()
             throws InterruptedException, TimeoutException {
         // Simulate a tap and make sure Content is not visible.
@@ -2447,7 +2455,6 @@
     /**
      * Tests that chained searches make Content visible when opening the Panel.
      */
-    @DisabledTest // https://crbug.com/551711
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
@@ -2502,7 +2509,6 @@
     /**
      * Tests that a tap followed by opening the Panel does not remove the loaded URL from history.
      */
-    @DisabledTest // https://crbug.com/551711
     @SmallTest
     @Feature({"ContextualSearch"})
     @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
@@ -2559,4 +2565,34 @@
         assertTrue(mFakeServer.hasRemovedUrl(url2));
         assertTrue(mFakeServer.hasRemovedUrl(url3));
     }
+
+    /**
+     * Tests that a simple Tap with language determination triggers translation.
+     */
+    @SmallTest
+    @Feature({"ContextualSearch"})
+    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @CommandLineFlags.Add(ContextualSearchFieldTrial.TRANSLATION_ONEBOX_ENABLED + "=true")
+    public void testTapWithLanguage() throws InterruptedException, TimeoutException {
+        // Tapping a german word should trigger translation.
+        simulateTapSearch("german");
+
+        // Make sure we tried to trigger translate.
+        assertTrue(mManager.getRequest().isTranslationForced());
+    }
+
+    /**
+     * Tests that a simple Tap without language determination does not trigger translation.
+     */
+    @SmallTest
+    @Feature({"ContextualSearch"})
+    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+    @CommandLineFlags.Add(ContextualSearchFieldTrial.TRANSLATION_ONEBOX_ENABLED + "=true")
+    public void testTapWithoutLanguage() throws InterruptedException, TimeoutException {
+        // Tapping an English word should NOT trigger translation.
+        simulateTapSearch("search");
+
+        // Make sure we did not try to trigger translate.
+        assertFalse(mManager.getRequest().isTranslationForced());
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java
index 0b04598..4d67136 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java
@@ -18,7 +18,6 @@
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.Callable;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
@@ -32,18 +31,16 @@
     @MediumTest
     @Feature({"Feedback"})
     public void testNormalCaseShouldWork() throws InterruptedException {
-        final ConnectivityTask task = ThreadUtils.runOnUiThreadBlockingNoException(
-                new Callable<ConnectivityTask>() {
-                    @Override
-                    public ConnectivityTask call() {
-                        // Intentionally make HTTPS-connection fail which should result in
-                        // NOT_CONNECTED.
-                        ConnectivityChecker.overrideUrlsForTest(GENERATE_204_URL,
-                                GENERATE_404_URL);
-                        return ConnectivityTask.create(Profile.getLastUsedProfile(), TIMEOUT_MS,
-                                null);
-                    }
-                });
+        final AtomicReference<ConnectivityTask> task = new AtomicReference<>();
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                // Intentionally make HTTPS-connection fail which should result in NOT_CONNECTED.
+                ConnectivityChecker.overrideUrlsForTest(GENERATE_204_URL, GENERATE_404_URL);
+
+                task.set(ConnectivityTask.create(Profile.getLastUsedProfile(), TIMEOUT_MS, null));
+            }
+        });
 
         boolean gotResult = CriteriaHelper.pollForUIThreadCriteria(new Criteria() {
             @Override
@@ -87,6 +84,7 @@
     @Feature({"Feedback"})
     public void testCallbackNormalCaseShouldWork() throws InterruptedException {
         final Semaphore semaphore = new Semaphore(0);
+        final AtomicReference<ConnectivityTask> task = new AtomicReference<>();
         final AtomicReference<FeedbackData> feedbackRef = new AtomicReference<>();
         final ConnectivityTask.ConnectivityResult callback =
                 new ConnectivityTask.ConnectivityResult() {
@@ -96,17 +94,17 @@
                 semaphore.release();
             }
         };
-        final ConnectivityTask task = ThreadUtils.runOnUiThreadBlockingNoException(
-                new Callable<ConnectivityTask>() {
-                    @Override
-                    public ConnectivityTask call() {
-                        // Intentionally make HTTPS-connection fail which should result in
-                        // NOT_CONNECTED.
-                        ConnectivityChecker.overrideUrlsForTest(GENERATE_204_URL, GENERATE_404_URL);
-                        return ConnectivityTask.create(Profile.getLastUsedProfile(), TIMEOUT_MS,
-                                callback);
-                    }
-                });
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                // Intentionally make HTTPS-connection fail which should result in NOT_CONNECTED.
+                ConnectivityChecker.overrideUrlsForTest(GENERATE_204_URL, GENERATE_404_URL);
+
+                task.set(ConnectivityTask.create(
+                        Profile.getLastUsedProfile(), TIMEOUT_MS, callback));
+            }
+        });
+
         if (!semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
             fail("Failed to acquire semaphore.");
         }
@@ -120,6 +118,7 @@
     public void testCallbackTwoTimeouts() throws InterruptedException {
         final int checkTimeoutMs = 100;
         final Semaphore semaphore = new Semaphore(0);
+        final AtomicReference<ConnectivityTask> task = new AtomicReference<>();
         final AtomicReference<FeedbackData> feedbackRef = new AtomicReference<>();
         final ConnectivityTask.ConnectivityResult callback =
                 new ConnectivityTask.ConnectivityResult() {
@@ -129,18 +128,16 @@
                 semaphore.release();
             }
         };
-        final ConnectivityTask task = ThreadUtils.runOnUiThreadBlockingNoException(
-                new Callable<ConnectivityTask>() {
-                    @Override
-                    public ConnectivityTask call() {
-                        // Intentionally make HTTPS connections slow which should result in
-                        // TIMEOUT.
-                        ConnectivityChecker.overrideUrlsForTest(GENERATE_204_URL,
-                                GENERATE_204_SLOW_URL);
-                        return ConnectivityTask.create(Profile.getLastUsedProfile(),
-                                checkTimeoutMs, callback);
-                    }
-                });
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                // Intentionally make HTTPS connections slow which should result in TIMEOUT.
+                ConnectivityChecker.overrideUrlsForTest(GENERATE_204_URL, GENERATE_204_SLOW_URL);
+
+                task.set(ConnectivityTask.create(
+                        Profile.getLastUsedProfile(), checkTimeoutMs, callback));
+            }
+        });
 
         if (!semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
             fail("Failed to acquire semaphore.");
@@ -155,23 +152,21 @@
     @MediumTest
     @Feature({"Feedback"})
     public void testTwoTimeoutsShouldFillInTheRest() throws InterruptedException {
-        final ConnectivityTask task = ThreadUtils.runOnUiThreadBlockingNoException(
-                new Callable<ConnectivityTask>() {
-                    @Override
-                    public ConnectivityTask call() {
-                        // Intentionally make HTTPS connections slow which should result in
-                        // UNKNOWN.
-                        ConnectivityChecker.overrideUrlsForTest(GENERATE_204_URL,
-                                GENERATE_204_SLOW_URL);
-                        return ConnectivityTask.create(Profile.getLastUsedProfile(), TIMEOUT_MS,
-                                null);
-                    }
-                });
+        final AtomicReference<ConnectivityTask> task = new AtomicReference<>();
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                // Intentionally make HTTPS connections slow which should result in UNKNOWN.
+                ConnectivityChecker.overrideUrlsForTest(GENERATE_204_URL, GENERATE_204_SLOW_URL);
+
+                task.set(ConnectivityTask.create(Profile.getLastUsedProfile(), TIMEOUT_MS, null));
+            }
+        });
 
         boolean gotResult = CriteriaHelper.pollForUIThreadCriteria(new Criteria() {
             @Override
             public boolean isSatisfied() {
-                return task.isDone();
+                return task.get().isDone();
             }
         }, TIMEOUT_MS / 5, RESULT_CHECK_INTERVAL_MS);
         assertFalse("Should not be finished by now.", gotResult);
@@ -208,14 +203,14 @@
         assertEquals("WiFi", map.get(ConnectivityTask.CONNECTION_TYPE_KEY));
     }
 
-    private static FeedbackData getResult(final ConnectivityTask task) {
-        final FeedbackData result = ThreadUtils.runOnUiThreadBlockingNoException(
-                new Callable<FeedbackData>() {
-                    @Override
-                    public FeedbackData call() {
-                        return task.get();
-                    }
-                });
-        return result;
+    private static FeedbackData getResult(final AtomicReference<ConnectivityTask> task) {
+        final AtomicReference<FeedbackData> result = new AtomicReference<>();
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                result.set(task.get().get());
+            }
+        });
+        return result.get();
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java
index fef1a323..7803b6a 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java
@@ -50,6 +50,7 @@
         public boolean shouldSkipFirstUseHints;
         public boolean isStableBuild;
         public boolean isFirstRunEulaAccepted;
+        public boolean shouldShowDataReductionPage;
 
         public TestFirstRunFlowSequencer(Activity activity, Bundle launcherProvidedProperties) {
             super(activity, launcherProvidedProperties);
@@ -102,6 +103,11 @@
         }
 
         @Override
+        public boolean shouldShowDataReductionPage() {
+            return shouldShowDataReductionPage;
+        }
+
+        @Override
         public void enableCrashUpload() {
             calledEnableCrashUpload = true;
         }
@@ -149,14 +155,17 @@
         mSequencer.hasAnyUserSeenToS = false;
         mSequencer.shouldSkipFirstUseHints = false;
         mSequencer.isStableBuild = true;
+        mSequencer.shouldShowDataReductionPage = false;
         mSequencer.processFreEnvironment(
                 false, // androidEduDevice
                 false); // hasChildAccount
         assertTrue(mSequencer.calledOnFlowIsKnown);
         assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
         assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertFalse(mSequencer.returnedBundle.getBoolean(
+                FirstRunActivity.SHOW_DATA_REDUCTION_PAGE));
         assertFalse(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
-        assertEquals(3, mSequencer.returnedBundle.size());
+        assertEquals(4, mSequencer.returnedBundle.size());
         assertFalse(mSequencer.calledEnableCrashUpload);
         assertFalse(mSequencer.calledSetFirstRunFlowSignInComplete);
     }
@@ -173,18 +182,21 @@
         mSequencer.hasAnyUserSeenToS = true;
         mSequencer.shouldSkipFirstUseHints = false;
         mSequencer.isStableBuild = true;
+        mSequencer.shouldShowDataReductionPage = false;
         mSequencer.processFreEnvironment(
                 false, // androidEduDevice
                 false); // hasChildAccount
         assertTrue(mSequencer.calledOnFlowIsKnown);
         assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
         assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertFalse(mSequencer.returnedBundle.getBoolean(
+                FirstRunActivity.SHOW_DATA_REDUCTION_PAGE));
         assertFalse(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
         assertTrue(mSequencer.returnedBundle.getBoolean(
                 AccountFirstRunFragment.PRESELECT_BUT_ALLOW_TO_CHANGE));
         assertEquals(DEFAULT_ACCOUNT, mSequencer.returnedBundle.getString(
                 AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO));
-        assertEquals(5, mSequencer.returnedBundle.size());
+        assertEquals(6, mSequencer.returnedBundle.size());
         assertFalse(mSequencer.calledEnableCrashUpload);
         assertFalse(mSequencer.calledSetFirstRunFlowSignInComplete);
     }
@@ -199,14 +211,17 @@
         mSequencer.hasAnyUserSeenToS = false;
         mSequencer.shouldSkipFirstUseHints = false;
         mSequencer.isStableBuild = false;
+        mSequencer.shouldShowDataReductionPage = false;
         mSequencer.processFreEnvironment(
                 false, // androidEduDevice
                 false); // hasChildAccount
         assertTrue(mSequencer.calledOnFlowIsKnown);
         assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
         assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertFalse(mSequencer.returnedBundle.getBoolean(
+                FirstRunActivity.SHOW_DATA_REDUCTION_PAGE));
         assertFalse(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
-        assertEquals(3, mSequencer.returnedBundle.size());
+        assertEquals(4, mSequencer.returnedBundle.size());
         assertTrue(mSequencer.calledEnableCrashUpload);
         assertFalse(mSequencer.calledSetFirstRunFlowSignInComplete);
     }
@@ -223,19 +238,46 @@
         mSequencer.hasAnyUserSeenToS = false;
         mSequencer.shouldSkipFirstUseHints = false;
         mSequencer.isStableBuild = true;
+        mSequencer.shouldShowDataReductionPage = false;
         mSequencer.processFreEnvironment(
                 false, // androidEduDevice
                 true); // hasChildAccount
         assertTrue(mSequencer.calledOnFlowIsKnown);
         assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
         assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertFalse(mSequencer.returnedBundle.getBoolean(
+                FirstRunActivity.SHOW_DATA_REDUCTION_PAGE));
         assertTrue(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
         assertFalse(mSequencer.returnedBundle.getBoolean(
                 AccountFirstRunFragment.PRESELECT_BUT_ALLOW_TO_CHANGE));
         assertEquals(DEFAULT_ACCOUNT, mSequencer.returnedBundle.getString(
                 AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO));
-        assertEquals(5, mSequencer.returnedBundle.size());
+        assertEquals(6, mSequencer.returnedBundle.size());
         assertFalse(mSequencer.calledEnableCrashUpload);
         assertTrue(mSequencer.calledSetFirstRunFlowSignInComplete);
     }
+
+    @Test
+    @Feature({"FirstRun"})
+    public void testStandardFlowShowDataReductionPage() {
+        mSequencer.isFirstRunFlowComplete = false;
+        mSequencer.isSignedIn = false;
+        mSequencer.isSyncAllowed = true;
+        mSequencer.googleAccounts = new Account[0];
+        mSequencer.hasAnyUserSeenToS = false;
+        mSequencer.shouldSkipFirstUseHints = false;
+        mSequencer.isStableBuild = true;
+        mSequencer.shouldShowDataReductionPage = true;
+        mSequencer.processFreEnvironment(
+                false, // androidEduDevice
+                false); // hasChildAccount
+        assertTrue(mSequencer.calledOnFlowIsKnown);
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE));
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE));
+        assertTrue(mSequencer.returnedBundle.getBoolean(FirstRunActivity.SHOW_DATA_REDUCTION_PAGE));
+        assertFalse(mSequencer.returnedBundle.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT));
+        assertEquals(4, mSequencer.returnedBundle.size());
+        assertFalse(mSequencer.calledEnableCrashUpload);
+        assertFalse(mSequencer.calledSetFirstRunFlowSignInComplete);
+    }
 }
diff --git a/chrome/app/DEPS b/chrome/app/DEPS
index cd3a112..14c8861 100644
--- a/chrome/app/DEPS
+++ b/chrome/app/DEPS
@@ -19,7 +19,7 @@
   "+components/nacl/renderer/plugin/ppapi_entrypoints.h",
   "+components/nacl/zygote",
   "+components/policy/core/browser/android",
-  "+components/startup_metric_utils/browser",
+  "+components/startup_metric_utils",
   "+components/upload_list",
   "+components/version_info",
   "+content/public/app",
diff --git a/chrome/app/android/chrome_main_delegate_android.cc b/chrome/app/android/chrome_main_delegate_android.cc
index f4440ca..dec88e9c 100644
--- a/chrome/app/android/chrome_main_delegate_android.cc
+++ b/chrome/app/android/chrome_main_delegate_android.cc
@@ -16,7 +16,7 @@
 #include "chrome/browser/android/metrics/uma_utils.h"
 #include "chrome/browser/media/android/remote/remote_media_player_manager.h"
 #include "components/policy/core/browser/android/android_combined_policy_provider.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "content/browser/media/android/browser_media_player_manager.h"
 #include "content/public/browser/browser_main_runner.h"
 
diff --git a/chrome/app/chrome_exe_main_mac.c b/chrome/app/chrome_exe_main_mac.c
new file mode 100644
index 0000000..8c0fc8c
--- /dev/null
+++ b/chrome/app/chrome_exe_main_mac.c
@@ -0,0 +1,90 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The entry point for all Mac Chromium processes, including the outer app
+// bundle (browser) and helper app (renderer, plugin, and friends).
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <libgen.h>
+#include <mach-o/dyld.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "chrome/common/chrome_version.h"
+
+typedef int (*ChromeMainPtr)(int, char**);
+
+__attribute__((visibility("default"))) int main(int argc, char* argv[]) {
+#if defined(HELPER_EXECUTABLE)
+  const char* const rel_path =
+      "../../../" PRODUCT_FULLNAME_STRING
+      " Framework.framework/" PRODUCT_FULLNAME_STRING " Framework";
+#else
+  const char* const rel_path =
+      "../Versions/" CHROME_VERSION_STRING "/" PRODUCT_FULLNAME_STRING
+      " Framework.framework/" PRODUCT_FULLNAME_STRING " Framework";
+#endif  // defined(HELPER_EXECUTABLE)
+
+  uint32_t exec_path_size = 0;
+  int rv = _NSGetExecutablePath(NULL, &exec_path_size);
+  if (rv != -1) {
+    fprintf(stderr,
+            "_NSGetExecutablePath: get [length|path] failed.\n");
+    abort();
+  }
+
+  char* exec_path = malloc(exec_path_size);
+  if (!exec_path) {
+    fprintf(stderr, "malloc %u: %s\n", exec_path_size, strerror(errno));
+    abort();
+  }
+
+  rv = _NSGetExecutablePath(exec_path, &exec_path_size);
+  if (rv != 0) {
+    fprintf(stderr,
+            "_NSGetExecutablePath(): get [%d|path] failed.\n", exec_path_size);
+    abort();
+  }
+
+  // Slice off the last part of the main executable path, and append the
+  // version framework information.
+  char* parent_dir = dirname(exec_path);
+  if (!parent_dir) {
+    fprintf(stderr, "dirname %s: %s\n", exec_path, strerror(errno));
+    abort();
+  }
+  free(exec_path);
+
+  size_t parent_path_len = strlen(parent_dir);
+  size_t rel_path_len = strlen(rel_path);
+  // 2 accounts for a trailing NUL byte and the '/' in the middle of the paths.
+  size_t framework_path_size = parent_path_len + rel_path_len + 2;
+  char* framework_path = malloc(framework_path_size);
+  if (!framework_path) {
+    fprintf(stderr, "malloc %zu: %s\n", framework_path_size, strerror(errno));
+    abort();
+  }
+  snprintf(framework_path, framework_path_size, "%s/%s", parent_dir, rel_path);
+
+  void* library = dlopen(framework_path, RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
+  if (!library) {
+    fprintf(stderr, "dlopen %s: %s\n", framework_path, dlerror());
+    abort();
+  }
+  free(framework_path);
+
+  ChromeMainPtr chrome_main = dlsym(library, "ChromeMain");
+  if (!chrome_main) {
+    fprintf(stderr, "dlsym ChromeMain: %s\n", dlerror());
+    abort();
+  }
+  rv = chrome_main(argc, argv);
+
+  // exit, don't return from main, to avoid the apparent removal of main from
+  // stack backtraces under tail call optimization.
+  exit(rv);
+}
diff --git a/chrome/app/chrome_exe_main_mac.cc b/chrome/app/chrome_exe_main_mac.cc
deleted file mode 100644
index 83a5c7c..0000000
--- a/chrome/app/chrome_exe_main_mac.cc
+++ /dev/null
@@ -1,21 +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.
-
-// The entry point for all Mac Chromium processes, including the outer app
-// bundle (browser) and helper app (renderer, plugin, and friends).
-
-#include <stdlib.h>
-
-extern "C" {
-int ChromeMain(int argc, char** argv);
-}  // extern "C"
-
-__attribute__((visibility("default")))
-int main(int argc, char* argv[]) {
-  int rv = ChromeMain(argc, argv);
-
-  // exit, don't return from main, to avoid the apparent removal of main from
-  // stack backtraces under tail call optimization.
-  exit(rv);
-}
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc
index a5f8ee1..d26676fe 100644
--- a/chrome/app/chrome_exe_main_win.cc
+++ b/chrome/app/chrome_exe_main_win.cc
@@ -21,7 +21,7 @@
 #include "chrome/common/chrome_paths_internal.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome_elf/chrome_elf_main.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "content/public/common/result_codes.h"
 #include "ui/gfx/win/dpi.h"
 
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index cb27994b..b6c7bac 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -40,6 +40,7 @@
 #include "chrome/utility/chrome_content_utility_client.h"
 #include "components/component_updater/component_updater_paths.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "components/version_info/version_info.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_paths.h"
@@ -125,10 +126,6 @@
 #include "pdf/pdf.h"
 #endif
 
-#if !defined(CHROME_MULTIPLE_DLL_CHILD)
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
-#endif
-
 #if !defined(CHROME_MULTIPLE_DLL_BROWSER)
 #include "chrome/child/pdf_child_init.h"
 
@@ -406,8 +403,9 @@
 }
 #endif
 
-#if !defined(CHROME_MULTIPLE_DLL_CHILD)
-void RecordMainStartupMetrics() {
+}  // namespace
+
+ChromeMainDelegate::ChromeMainDelegate() {
 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)
   // Record the startup process creation time on supported platforms.
   startup_metric_utils::RecordStartupProcessCreationTime(
@@ -423,19 +421,6 @@
   startup_metric_utils::RecordMainEntryPointTime(base::Time::Now());
 #endif
 }
-#endif  // !defined(CHROME_MULTIPLE_DLL_CHILD)
-
-}  // namespace
-
-ChromeMainDelegate::ChromeMainDelegate() {
-#if !defined(CHROME_MULTIPLE_DLL_CHILD)
-  // Record startup metrics in the browser process. For component builds, there
-  // is no way to know the type of process (process command line is not yet
-  // initialized), so the function below will also be called in renderers.
-  // This doesn't matter as it simply sets global variables.
-  RecordMainStartupMetrics();
-#endif  // !defined(CHROME_MULTIPLE_DLL_CHILD)
-}
 
 ChromeMainDelegate::~ChromeMainDelegate() {
 }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 28b0809..efe187c7 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -12017,14 +12017,6 @@
         Your data is encrypted with your sync passphrase. Please enter it below.
       </message>
 
-      <!-- Sync time strings -->
-      <message name="IDS_SYNC_TIME_NEVER" desc="Indicates that the first sync has never completed.">
-        Never
-      </message>
-      <message name="IDS_SYNC_TIME_JUST_NOW" desc="Indicates that a sync cycle just finished.">
-        Just now
-      </message>
-
       <!-- Sync/sign-in error messages -->
       <message name="IDS_SIGNIN_ERROR_BUBBLE_VIEW_TITLE" desc="Title in the sign-in error bubble view/notification.">
         Sign-in Error
@@ -12821,10 +12813,10 @@
           Downloads
         </message>
         <message name="IDS_WINDOW_AUDIO_PLAYING_MAC" desc="The emoji to append to the title of a window showing audio is playing.">
-          <ph name="TAB_TITLE">$1<ex>The Title of the Tab</ex></ph> 🔊
+          <ph name="TAB_TITLE">$1<ex>The Title of the Tab</ex></ph> (audio)
         </message>
         <message name="IDS_WINDOW_AUDIO_MUTING_MAC" desc="The emoji to append to the title of a window showing audio is muting.">
-          <ph name="TAB_TITLE">$1<ex>The Title of the Tab</ex></ph> 🔇
+          <ph name="TAB_TITLE">$1<ex>The Title of the Tab</ex></ph> (muted)
         </message>
         <message name="IDS_SHOW_EXTENSIONS_MAC" desc="The Mac menu item to show extensions in the window menu.">
           Extensions
diff --git a/chrome/app/resources/address_input_strings_hu.xtb b/chrome/app/resources/address_input_strings_hu.xtb
index 883ae3d..aeafa65 100644
--- a/chrome/app/resources/address_input_strings_hu.xtb
+++ b/chrome/app/resources/address_input_strings_hu.xtb
@@ -20,7 +20,7 @@
 <translation id="6132429659673988671">Külváros</translation>
 <translation id="6207937957461833379">Ország/Régió</translation>
 <translation id="6247152910634872706">Szervezet</translation>
-<translation id="6271429879296260742">PIN kód</translation>
+<translation id="6271429879296260742">PIN-kód</translation>
 <translation id="6282194474023008486">Irányítószám</translation>
 <translation id="6327653052522436195">Település</translation>
 <translation id="6403469950615936250">Ezt az irányítószámot nem lehet felismerni. Példa egy érvényes irányítószámra: <ph name="EXAMPLE" />. Nem tudja irányítószámát? Keresse meg <ph name="BEGIN_LINK" />itt<ph name="END_LINK" />.</translation>
diff --git a/chrome/app/resources/chromium_strings_fa.xtb b/chrome/app/resources/chromium_strings_fa.xtb
index 26a6f03..000e88a 100644
--- a/chrome/app/resources/chromium_strings_fa.xtb
+++ b/chrome/app/resources/chromium_strings_fa.xtb
@@ -190,7 +190,7 @@
 <translation id="7162152143154757523">‏Chromium می‌تواند با ارسال مواردی که در مرورگر تایپ‌ می‌کنید به سرورهای Google، غلط گیر املایی هوشمندانه‌تری به شما ارائه دهد و به شما امکان دهد از همان فناوری غلط گیر املایی استفاده شده در جستجوی Google استفاده کنید.</translation>
 <translation id="7196020411877309443">چرا من این را می‌بینم؟</translation>
 <translation id="7205698830395646142">‏پنهان در منوی Chromium</translation>
-<translation id="7211828883345145708">‏میانبرهای دیگر صفحه کلید را فعال می‌کند که برای اشکال زدایی Chromium مفید هستند.</translation>
+<translation id="7211828883345145708">‏میان‌برهای دیگر صفحه‌کلید را فعال می‌کند که برای اشکال زدایی Chromium مفید هستند.</translation>
 <translation id="7223968959479464213">‏مدیر فعالیت‌ها - Chromium</translation>
 <translation id="722928257909516027">‏نمایش منوی Chromium</translation>
 <translation id="731644333568559921">‏به‌روزرسانی &amp;سیستم عامل Chromium</translation>
diff --git a/chrome/app/resources/chromium_strings_no.xtb b/chrome/app/resources/chromium_strings_no.xtb
index 8f35a1c6..8379a85 100644
--- a/chrome/app/resources/chromium_strings_no.xtb
+++ b/chrome/app/resources/chromium_strings_no.xtb
@@ -37,7 +37,7 @@
 <translation id="2233513990531887259">Start på nytt i maksimert modus for Chromium</translation>
 <translation id="2241627712206172106">Hvis du deler en datamaskin med andre, kan venner og familie surfe hver for seg og konfigurere Chromium akkurat slik de vil.</translation>
 <translation id="225614027745146050">Velkommen</translation>
-<translation id="2316129865977710310">Nei takk</translation>
+<translation id="2316129865977710310">Nei, takk</translation>
 <translation id="2347108572062610441">Denne utvidelsen har endret hvilken side som vises når du starter Chromium.</translation>
 <translation id="2389622953163669926">{NUM_DOWNLOAD,plural, =1{En nedlasting pågår for øyeblikket. Vil du avbryte nedlastingen og avslutte Chromium?}other{# nedlastinger pågår for øyeblikket. Vil du avbryte nedlastingene og avslutte Chromium?}}</translation>
 <translation id="2396765026452590966">Utvidelsen «<ph name="EXTENSION_NAME" />» har endret hvilken side som vises når du starter Chromium.</translation>
@@ -205,7 +205,7 @@
 <translation id="7419987137528340081">Hvis du foretrekker å holde eksisterende Chromium-data separat, kan du opprette en ny Chromium-bruker for <ph name="USER_NAME" />.</translation>
 <translation id="7421823331379285070">Chromium krever Windows XP eller nyere. Enkelte funksjoner vil kanskje ikke fungere.</translation>
 <translation id="7463979740390522693">Chromium – varsler (<ph name="QUANTITY" /> uleste)</translation>
-<translation id="7473891865547856676">Nei takk</translation>
+<translation id="7473891865547856676">Nei, takk</translation>
 <translation id="7483335560992089831">Kan ikke installere den samme Chromium-versjonen som kjører. Lukk Chromium og prøv på nytt.</translation>
 <translation id="750717762378961310">Denne filen er skadelig, og Chromium har blokkert den.</translation>
 <translation id="7549178288319965365">Om Chromium OS</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb
index f4b0b24..8c3320c 100644
--- a/chrome/app/resources/generated_resources_am.xtb
+++ b/chrome/app/resources/generated_resources_am.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">ከእነዚህ የዩኤስቢ መሣሪያዎች ውስጥ ማንኛቸውም ይደርስባቸዋል</translation>
 <translation id="1038168778161626396">ምስጢራዊ ማድረግ ብቻ</translation>
 <translation id="1038842779957582377">ያልታወቀ ስም</translation>
-<translation id="1040931876666128942">የWebUsb ማሳወቂያዎች።</translation>
 <translation id="1042174272890264476">እንዲሁም ኮምፒውተርዎ የ<ph name="SHORT_PRODUCT_NAME" /> RLZ ቤተ-ፍርግም አብሮ ተሰርቶለት ነው የሚመጣው። RLZ ፍለጋዎችን እና በአንድ የተወሰነ የማስተዋወቂያ ዘመቻ የሚነዳ የ<ph name="SHORT_PRODUCT_NAME" /> አጠቃቀምን ለመለካት ልዩ ያልሆነ፣ በግል ሊለይ የማይችል መለያ ይመድባል። እነዚህ መለያ ስሞች አንዳንድ ጊዜ በ<ph name="PRODUCT_NAME" /> የGoogle ፍለጋ መጠይቆች ላይ ይታያሉ።</translation>
 <translation id="1042574203789536285"><ph name="URL" /> ትልቅ ውሂብ በእርስዎ መሣሪያ ላይ እስከ መጨረሻው ማከማቸት ይፈልጋል።</translation>
 <translation id="1045157690796831147">በቋንቋ ፊደል መጻፍ (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">አዲስ የኩኪ ቅንብሮች ገጹ ዳግም ከተጫነ በኋላ ይተገበራሉ።</translation>
 <translation id="14720830734893704">የምናባዊ የቁልፍ ሰሌዳ ድጋፍን አንቃ።</translation>
 <translation id="1474339897586437869">«<ph name="FILENAME" />» አልተሰቀለም። በእርስዎ Google Drive ውስጥ በቂ የሆነ ነፃ ቦታ የለም።</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 የይለፍ ቃል}one{# የይለፍ ቃሎች}other{# የይለፍ ቃሎች}}</translation>
 <translation id="1476949146811612304">ከ<ph name="BEGIN_LINK" />ኦምኒቦክሱ<ph name="END_LINK" /> ሲፈለግ የትኛው የፍለጋ ፕሮግራም ስራ ላይ እንደሚውል ያዘጋጃል።</translation>
 <translation id="1477301030751268706">የመታወቂያ ኤ ፒ አይ ማስመሰያ መሸጎጫ</translation>
 <translation id="1478340334823509079">ዝርዝሮች፦ <ph name="FILE_NAME" /></translation>
@@ -929,6 +927,7 @@
 <translation id="2326606747676847821">ማንነት ወደማያሳውቅ ሁነታ ሂድ</translation>
 <translation id="2326931316514688470">&amp;መተግበሪያን ዳግም ጫን</translation>
 <translation id="2327492829706409234">መተግበሪያን አንቃ</translation>
+<translation id="2329597144923131178">የእርስዎን ዕልባቶች፣ ታሪክ፣ የይለፍ ቃላት እና ሌሎች ቅንብሮች በሁሉም መሣሪያዎችዎ ላይ ለማግኘት ወደ መለያ ይግቡ።</translation>
 <translation id="2332131598580221120">በመደብር ውስጥ ይመልከቱ</translation>
 <translation id="2332742915001411729">ወደ ነባሪ ዳግም አስጀምር</translation>
 <translation id="2335122562899522968">ይህ ገጽ ኩኪዎችን አዋቅሯል።</translation>
@@ -952,7 +951,6 @@
 <translation id="2359808026110333948">ቀጥል</translation>
 <translation id="236128817791440714">የሚመከር፦ Smart Lock ለAndroidን ያቀናብሩ</translation>
 <translation id="236141728043665931">ሁልጊዜ የማይክሮፎን መዳረሻ አግድ</translation>
-<translation id="2365626167708453863">አንድ መለያ ከእርስዎ Google Smart Lock ይምረጡ</translation>
 <translation id="2367972762794486313">መተግበሪያዎችን አሳይ</translation>
 <translation id="2368075211218459617">አግባቡን ያጣቀሰ ፍለጋን አንቃ።</translation>
 <translation id="2370882663124746154">ድርብ-በቻይና ፊደል መጻፊያ ሁነታን ያንቁ</translation>
@@ -2667,7 +2665,6 @@
 <translation id="4780374166989101364">የሙከራ ቅጥያ ኤ ፒ አይዎችን ያነቃል። ማዕከለ-ቅጥያው የሙከራ ቅጥያ ኤ ፒ አይዎችን የሚጠቀሙ ቅጥያዎች እንዲሰቅሉ እንደማይፈቅድልዎት ልብ ይበሉ።</translation>
 <translation id="4781787911582943401">ማያ ገጽን አጉላ</translation>
 <translation id="4782449893814226250">ይህን ገጽ መጎብኘት ችግር ካለው ጠይቀዋል።</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 ኪባ}one{# ኪባ}other{# ኪባ}}</translation>
 <translation id="4784330909746505604">PowerPoint ማቅረቢያ</translation>
 <translation id="4785040501822872973">ይህ ኮምፒውተር በ<ph name="LOGOUT_TIME_LEFT" /> ሰከንዶች ውስጥ ዳግም ይጀምራል።
 ማሰስ ለመቀጠል ማንኛውም ቁልፍ ይጫኑ።</translation>
@@ -3200,7 +3197,6 @@
 <translation id="5527474464531963247">ሌላ አውታረ መረብ መምረጥም ይችላሉ።</translation>
 <translation id="5527963985407842218">የአንባቢ ሁነታ ማስጀመር</translation>
 <translation id="5528368756083817449">ዕልባት አስተዳዳሪ</translation>
-<translation id="5529098031581368697">የአሁኑ ልጣፍ  በ«<ph name="APP_NAME" />» ነው የተዘጋጀው</translation>
 <translation id="5531274207066050939">Google ክፍያዎች</translation>
 <translation id="5532223876348815659">ሁሉንም</translation>
 <translation id="5533555070048896610">በቋንቋ ፊደል መጻፍ (namaste → नमस्ते)</translation>
@@ -3316,7 +3312,6 @@
 <translation id="5702898740348134351">&amp;የፍለጋ ፕሮግራሞችን አርትዕ...</translation>
 <translation id="5703594190584829406">ከdropdown ውስጥ ይልቅ በቁልፍ ሰሌዳ አናት ላይ ራስ-ሰር ጥቆማ ሃሳቦችን ያሳያል።</translation>
 <translation id="5704272569086782895">ተከታታይ የጂፒዩ ራስተር ስራን አንቃ።</translation>
-<translation id="570544101664452060">የሙከራ WebUsb ማሳወቂያዎች።</translation>
 <translation id="5706551819490830015">የማስከፈያ አድራሻዎችን አቀናብር...</translation>
 <translation id="5707185214361380026">ቅጥያዎችን ከሚከተለው መጫን አልተቻለም፦</translation>
 <translation id="5707604204219538797">ቀጣይ ቃል</translation>
@@ -3463,7 +3458,6 @@
 <translation id="5900302528761731119">Google የመገለጫ ፎቶ</translation>
 <translation id="5900623698597156974">TLS 1.0 fallback ከአገልጋዩ ጋር እጅ ለእጅ መጨባበጥ ችሎ ነበር፣ ነገር ግን በፕሮቶኮሉ ላይ በደረሱ አዳዲስ ጥቃቶች ምክንያት ከዚህ በኋላ TLS 1.0 fallbacks አንቀበልም። አገልጋዩ TLS 1.2ን የስሪት ድርድርን በትክክል በስራ ላይ እንዲያውል እና በተመራጭነት እንዲደገፍ መዘመን ያስፈልገዋል።</translation>
 <translation id="590253956165195626">በሚያነብቡት ቋንቋ ያልሆኑ ገፆችን እንዲተረጎሙ ያቅርቡ።</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 ንጥል}one{# ንጥሎች}other{# ንጥሎች}}</translation>
 <translation id="5904093760909470684">የተኪ ውቅር</translation>
 <translation id="5906065664303289925">የሃርድዌር አድራሻ፦</translation>
 <translation id="5910363049092958439">ምስል አስ&amp;ቀምጥ እንደ…</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb
index e6a80f6e..887cf1b 100644
--- a/chrome/app/resources/generated_resources_ar.xtb
+++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">‏الدخول إلى أي من أجهزة USB هذه</translation>
 <translation id="1038168778161626396">التشفير فقط</translation>
 <translation id="1038842779957582377">اسم غير معروف</translation>
-<translation id="1040931876666128942">‏إشعارات WebUsb.</translation>
 <translation id="1042174272890264476">‏يأتي جهاز الكمبيوتر أيضًا مزودًا بمكتبة RLZ مضمنة للمنتج <ph name="SHORT_PRODUCT_NAME" />. تعيّن RLZ علامة غير فريدة وغير متعلقة بتحديد الشخصية من أجل قياس عمليات البحث ومعدل استخدام <ph name="SHORT_PRODUCT_NAME" /> الذي تؤثر فيه حملة ترويجية محددة. تظهر هذه التصنيفات أحيانًا في طلبات بحث Google في <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285">يريد <ph name="URL" /> تخزين البيانات الكبيرة بشكل دائم على جهازك.</translation>
 <translation id="1045157690796831147">‏التحويل الصوتي (ناماسكار ← നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">ستسري إعدادات ملفات تعريف الارتباط بعد إعادة تحميل الصفحة.</translation>
 <translation id="14720830734893704">تمكين إتاحة لوحة المفاتيح الظاهرية.</translation>
 <translation id="1474339897586437869">‏لم يتم تحميل "<ph name="FILENAME" />". حيث لا توجد لديك مساحة فارغة كافية في Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{كلمة مرور واحدة}zero{# كلمات مرور}two{ # كلمتا مرور}few{# كلمات مرور}many{# كلمة مرور}other{# من كلمات المرور}}</translation>
 <translation id="1476949146811612304">تعيين محرك البحث الذي يتم استخدامه عند البحث في
         <ph name="BEGIN_LINK" />المربع متعدد الاستخدامات<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">ذاكرة التخزين المؤقت للرمز المميز لواجهة برمجة تطبيقات الهوية</translation>
@@ -920,6 +918,7 @@
 <translation id="2326606747676847821">الانتقال إلى وضع التصفُّح المتخفّي</translation>
 <translation id="2326931316514688470">&amp;إعادة تحميل التطبيق</translation>
 <translation id="2327492829706409234">تمكين التطبيق</translation>
+<translation id="2329597144923131178">سجّل الدخول للحصول على الإشارات المرجعية، والسجل، وكلمات المرور، والإعدادات الأخرى على كل أجهزتك.</translation>
 <translation id="2332131598580221120">عرض في المتجر</translation>
 <translation id="2332742915001411729">إعادة تعيين على الإعدادات الافتراضية</translation>
 <translation id="2335122562899522968">تُعين هذه الصفحة ملفات تعريف الارتباط.</translation>
@@ -943,7 +942,6 @@
 <translation id="2359808026110333948">المتابعة</translation>
 <translation id="236128817791440714">‏مُقترح: إعداد Smart Lock لجهاز Android</translation>
 <translation id="236141728043665931">حظر الدخول إلى الميكروفون دومًا</translation>
-<translation id="2365626167708453863">‏اختيار حساب من Smart Lock من Google</translation>
 <translation id="2367972762794486313">إظهار التطبيقات</translation>
 <translation id="2368075211218459617">تمكين البحث السياقي.</translation>
 <translation id="2370882663124746154">تمكين وضع "بين ين" المزدوج</translation>
@@ -2650,7 +2648,6 @@
 <translation id="4780374166989101364">لتمكين واجهات برمجة التطبيقات التجريبية للإضافة. لاحظ أن معرض الإضافات لا يسمح لك بتحميل الإضافات التي تستخدم واجهات برمجة تطبيقات تجريبية.</translation>
 <translation id="4781787911582943401">تكبير الشاشة</translation>
 <translation id="4782449893814226250">لقد سألت والديك ما إذا كان مناسبًا لك زيارة هذه الصفحة.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{كيلوبايت واحد}zero{# كيلو بايت}two{كيلوبايتان اثنان #}few{# كيلوبايتات}many{# كيلوبايتًا}other{# من الكيلوبايتات}}</translation>
 <translation id="4784330909746505604">‏عرض تقديمي من PowerPoint</translation>
 <translation id="4785040501822872973">ستتم إعادة تعيين هذا الكمبيوتر في خلال <ph name="LOGOUT_TIME_LEFT" /> ثانية.
 اضغط على أي مفتاح لمتابعة الاستكشاف.</translation>
@@ -3180,7 +3177,6 @@
 <translation id="5527474464531963247">يمكنك أيضا تحديد شبكة أخرى.</translation>
 <translation id="5527963985407842218">تشغيل وضع القارئ</translation>
 <translation id="5528368756083817449">مدير الإشارات</translation>
-<translation id="5529098031581368697">الخلفية الحالية من إعداد "<ph name="APP_NAME" />"</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">عام</translation>
 <translation id="5533555070048896610">‏التحويل الصوتي (ناماستي ← नमस्ते)</translation>
@@ -3296,7 +3292,6 @@
 <translation id="5702898740348134351">&amp;تعديل محركات البحث...</translation>
 <translation id="5703594190584829406">تظهر اقتراحات الملء التلقائي في أعلى لوحة المفاتيح بدلاً من القائمة المنسدلة.</translation>
 <translation id="5704272569086782895">تمكين المسح المجالي لوحدة معالجة الرسومات التي تتضمن سلسلة من المحادثات</translation>
-<translation id="570544101664452060">‏إشعارات WebUsb التجريبية.</translation>
 <translation id="5706551819490830015">إدارة عناوين إرسال الفواتير...</translation>
 <translation id="5707185214361380026">فشل تحميل الإضافة من:</translation>
 <translation id="5707604204219538797">الكلمة التالية</translation>
@@ -3443,7 +3438,6 @@
 <translation id="5900302528761731119">‏صورة الملف الشخصي في Google</translation>
 <translation id="5900623698597156974">تُمكن طبقة النقل الآمنة 1.0 الاحتياطية من تأكيد الاتصال بالخادم، لكننا لم نعد نقبل طبقة النقل الآمنة 1.0 الاحتياطية. يلزم تحديث الخادم لتنفيذ تفاوض الإصدار بشكل صحيح ودعم طبقة النقل الآمنة 1.2 بشكل أفضل.</translation>
 <translation id="590253956165195626">عرض ترجمة الصفحات المكتوبة بلغة بخلاف لغتك.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{عنصر واحد}zero{# عناصر}two{عنصران #}few{# عناصر}many{# عنصرًا}other{# من العناصر}}</translation>
 <translation id="5904093760909470684">تهيئة الخادم الوكيل</translation>
 <translation id="5906065664303289925">عنوان الأجهزة:</translation>
 <translation id="5910363049092958439">حفظ ال&amp;صورة باسم...</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb
index 520c103..8aea76c5 100644
--- a/chrome/app/resources/generated_resources_bg.xtb
+++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Достъп до всяко от тези USB устройства</translation>
 <translation id="1038168778161626396">Само шифроване</translation>
 <translation id="1038842779957582377">неизвестно име</translation>
-<translation id="1040931876666128942">Известия от WebUsb.</translation>
 <translation id="1042174272890264476">Компютърът ви също се предлага с библиотеката RLZ на <ph name="SHORT_PRODUCT_NAME" />, която е вградена. Тя задава неуникален и непозволяващ лично идентифициране маркер за измерване на търсенията и използването на <ph name="SHORT_PRODUCT_NAME" />, стимулирани от определена промоционална кампания. Тези етикети понякога се показват в заявките за търсене с Google в <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> иска да съхранява за постоянно голямо количество данни на устройството ви.</translation>
 <translation id="1045157690796831147">Транслитерация (namaskar → നമസ്കാരം)</translation>
@@ -327,7 +326,6 @@
 <translation id="1470719357688513792">Новите настройки за „бисквитките“ ще влязат в сила след презареждането на страницата.</translation>
 <translation id="14720830734893704">Активирайте поддръжката за виртуална клавиатура.</translation>
 <translation id="1474339897586437869">Файлът „<ph name="FILENAME" />“ не бе качен. Нямате достатъчно свободно място в Google Диск.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 парола}other{# пароли}}</translation>
 <translation id="1476949146811612304">Задайте коя търсеща машина да се използва при търсене от <ph name="BEGIN_LINK" />полето за всичко<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Кеш на означенията за приложния програмен интерфейс (API) за самоличност</translation>
 <translation id="1478340334823509079">Подробности: <ph name="FILE_NAME" /></translation>
@@ -915,6 +913,7 @@
 <translation id="2326606747676847821">„Инкогнито“</translation>
 <translation id="2326931316514688470">&amp;Презареждане на приложението</translation>
 <translation id="2327492829706409234">Активиране на приложението</translation>
+<translation id="2329597144923131178">Влезте в профила си и получете своите отметки, история, пароли и др. настройки на всички у-ва.</translation>
 <translation id="2332131598580221120">Преглед в магазина</translation>
 <translation id="2332742915001411729">Възстановяване на настройката по подразбиране</translation>
 <translation id="2335122562899522968">Тази страница задава „бисквитки“.</translation>
@@ -938,7 +937,6 @@
 <translation id="2359808026110333948">Напред</translation>
 <translation id="236128817791440714">Препоръчително: Настройте Smart Lock за Android</translation>
 <translation id="236141728043665931">Достъпът до микрофона да се блокира винаги</translation>
-<translation id="2365626167708453863">Изберете профил от Google Smart Lock</translation>
 <translation id="2367972762794486313">Показване на приложенията</translation>
 <translation id="2368075211218459617">Активиране на контекстното търсене.</translation>
 <translation id="2370882663124746154">Активиране на режим „двоен пинин“</translation>
@@ -2639,7 +2637,6 @@
 <translation id="4780374166989101364">Активира експериментални приложни програмни интерфейси (API) за разширения. Обърнете внимание, че галерията с разширения не ви позволява да качвате такива, които използват експериментални приложни програмни интерфейси.</translation>
 <translation id="4781787911582943401">Увеличаване на мащаба на екрана</translation>
 <translation id="4782449893814226250">Попитахте родителите си дали може да посетите тази страница.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 КБ}other{# КБ}}</translation>
 <translation id="4784330909746505604">Презентация в PowerPoint</translation>
 <translation id="4785040501822872973">Този компютър ще се рестартира след <ph name="LOGOUT_TIME_LEFT" /> секунди.
 Натиснете който и да е клавиш, за да продължите да разглеждате.</translation>
@@ -3170,7 +3167,6 @@
 <translation id="5527474464531963247">Можете също да изберете друга мрежа.</translation>
 <translation id="5527963985407842218">Задействане на режима за четене</translation>
 <translation id="5528368756083817449">Диспечер на отметките</translation>
-<translation id="5529098031581368697">Текущият тапет е зададен от <ph name="APP_NAME" /></translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Глобално</translation>
 <translation id="5533555070048896610">Транслитерация (namaste → नमस्ते)</translation>
@@ -3287,7 +3283,6 @@
 <translation id="5702898740348134351">&amp;Редактиране на търсещите машини...</translation>
 <translation id="5703594190584829406">Предложенията за автоматично попълване се показват в горната част на клавиатурата вместо в падащо меню.</translation>
 <translation id="5704272569086782895">Активиране на растеризиране с графичния процесор в отделна нишка.</translation>
-<translation id="570544101664452060">Експериментални известия от WebUsb.</translation>
 <translation id="5706551819490830015">Управление на адресите за фактуриране...</translation>
 <translation id="5707185214361380026">Неуспешно зареждане на разширение от:</translation>
 <translation id="5707604204219538797">Следващата дума</translation>
@@ -3434,7 +3429,6 @@
 <translation id="5900302528761731119">Снимка на потребителския профил в Google</translation>
 <translation id="5900623698597156974">TLS 1.0 успя да осъществи диалог със сървъра, но вече не приемаме използването на този протокол като резервна опция. Трябва да актуализирате сървъра (предпочита се да поддържа TLS 1.2), така че да внедрите правилно съгласуването на версията.</translation>
 <translation id="590253956165195626">Извеждане на предложение за превод на страниците, които не са на четим от вас език.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 елемент}other{# елемента}}</translation>
 <translation id="5904093760909470684">Конфигурация на прокси сървър</translation>
 <translation id="5906065664303289925">Хардуерен адрес:</translation>
 <translation id="5910363049092958439">&amp;Запазване на изображението като...</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb
index 54fc140..5e6b079 100644
--- a/chrome/app/resources/generated_resources_bn.xtb
+++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">এই USB ডিভাইসগুলির মধ্যে যে কোনোটি অ্যাক্সেস করুন</translation>
 <translation id="1038168778161626396">কেবলমাত্র চিহ্ন প্রদান</translation>
 <translation id="1038842779957582377">অজানা নাম</translation>
-<translation id="1040931876666128942">WebUsb বিজ্ঞপ্তিগুলি।</translation>
 <translation id="1042174272890264476">আপনার কম্পিউটারও <ph name="SHORT_PRODUCT_NAME" /> এর RLZ লাইব্রেরি বিল্ট ইনের সাথে আসে৷ RLZ অনুসন্ধানগুলি পরিমাপ করার জন্য একটি সাধারণ, ব্যক্তিগতভাবে সনাক্তকরণযোগ্য নয় এমন ট্যাগ নির্ধারণ করে এবং <ph name="SHORT_PRODUCT_NAME" /> এর ব্যবহার একটি নির্দিষ্ট প্রচারাভিযানের মাধ্যমে চালিত হয়৷ এই লেবেলগুলি কখনো কখনো <ph name="PRODUCT_NAME" /> এ Google অনুসন্ধান ক্যোয়ারিগুলিতে প্রদর্শিত হয়৷</translation>
 <translation id="1042574203789536285"><ph name="URL" /> আপনার ডিভাইসে স্থায়ীভাবে বিপুল ডেটা জমা করতে চায়৷</translation>
 <translation id="1045157690796831147">লিপ্যন্তরকরণ (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">পৃষ্ঠা পুনরায় লোড হওয়ার পরে নতুন কুকি সেটিংস প্রভাবিত হবে৷</translation>
 <translation id="14720830734893704">ভার্চুয়াল কীবোর্ড সহায়তা সক্ষম করুন৷</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" আপলোড করা হয়নি। আপনার Google ড্রাইভে পর্যাপ্ত ফাঁকা স্থান নেই।</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{১টি পাসওয়ার্ড}one{#টি পাসওয়ার্ড}other{#টি পাসওয়ার্ড}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />বহূউপযোগী ক্ষেত্র<ph name="END_LINK" />.
 থেকে অনুসন্ধানের সময় কোন অনুসন্ধান ইঞ্জিন ব্যবহার করা হবে তা সেট করুন৷</translation>
 <translation id="1477301030751268706">পরিচয় API টোকেন ক্যাশে</translation>
@@ -928,6 +926,7 @@
 <translation id="2326606747676847821">ছদ্মবেশে যান</translation>
 <translation id="2326931316514688470">&amp;অ্যাপ্লিকেশান পুনরায় লোড করুন</translation>
 <translation id="2327492829706409234">অ্যাপ্লিকেশন সক্ষম করুন</translation>
+<translation id="2329597144923131178">আপনার সকল ডিভাইসে আপনার বুকমার্ক, ইতিহাস, পাসওয়ার্ড এবং অন্যান্য সেটিংস পেতে সাইন ইন করুন।</translation>
 <translation id="2332131598580221120">দোকানে দেখুন</translation>
 <translation id="2332742915001411729">ডিফল্টে পুনরায় সেট করুন</translation>
 <translation id="2335122562899522968">এই পৃষ্ঠাটি কুকি সেট করে৷</translation>
@@ -951,7 +950,6 @@
 <translation id="2359808026110333948">অবিরত</translation>
 <translation id="236128817791440714">প্রস্তাবিত: Android এর জন্য Smart Lock সেট আপ করুন</translation>
 <translation id="236141728043665931">মাইক্রোফোনের অ্যাক্সেস সর্বদা অবরুদ্ধ রাখুন</translation>
-<translation id="2365626167708453863">আপনার Google Smart Lock থেকে একটি অ্যাকাউন্ট চয়ন করুন</translation>
 <translation id="2367972762794486313">অ্যাপ্লিকেশানগুলি দেখান</translation>
 <translation id="2368075211218459617">প্রাসঙ্গিক অনুসন্ধান সক্ষম করুন৷</translation>
 <translation id="2370882663124746154">Double-Pinyin মোড সক্ষম করুন</translation>
@@ -2658,7 +2656,6 @@
 <translation id="4780374166989101364">পরীক্ষামূলক এক্সটেনশন APIগুলি সক্ষম করে৷ নোট করুন যে এক্সটেনশন গ্যালারীটি আপনাকে পরীক্ষামূলক APIগুলি ব্যবহার করে এমন এক্সটেনশনগুলি আপলোড করার অনুমতি দেয় না৷</translation>
 <translation id="4781787911582943401">স্ক্রিন জুম করুন</translation>
 <translation id="4782449893814226250">এই পৃষ্ঠাটি দেখার জন্য উপযুক্ত কিনা তা আপনি আপনার মাতাপিতাকে জিজ্ঞাসা করেছেন৷</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{১ kB}one{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint presentation</translation>
 <translation id="4785040501822872973">এই কম্পিউটার <ph name="LOGOUT_TIME_LEFT" /> সেকেন্ডে পুনঃসেট হবে৷ অনুসন্ধান চালাতে যে কোনো একটি কী টিপুন৷</translation>
 <translation id="4786993863723020412">ক্যাশে পঠনে ত্রুটি</translation>
@@ -3187,7 +3184,6 @@
 <translation id="5527474464531963247">আপনি হয়ত অন্য নেটওয়ার্ক নির্বাচন করতে পারেন৷</translation>
 <translation id="5527963985407842218">পাঠক মোডের ট্রিগার করা</translation>
 <translation id="5528368756083817449">বুকমার্ক পরিচালক</translation>
-<translation id="5529098031581368697"><ph name="APP_NAME" /> দ্বারা বর্তমান ওয়ালপেপার সেট করা হয়েছে</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">সার্বিক</translation>
 <translation id="5533555070048896610">লিপ্যন্তরকরণ (namaste → नमस्ते)</translation>
@@ -3302,7 +3298,6 @@
 <translation id="5702898740348134351">&amp;সার্চ ইঞ্জিন সম্পাদনা...</translation>
 <translation id="5703594190584829406">কোনো ড্রপডাউনের পরিবর্তে কীবোর্ডের শীর্ষে স্বতঃপূর্ণ প্রস্তাবনাগুলি দেখায়৷</translation>
 <translation id="5704272569086782895">থ্রেড করা GPU রাস্টারাইজেশান সক্ষম করুন৷</translation>
-<translation id="570544101664452060">পরীক্ষামূলক WebUsb বিজ্ঞপ্তিগুলি।</translation>
 <translation id="5706551819490830015">বিলিং ঠিকানাগুলি পরিচালনা করুন...</translation>
 <translation id="5707185214361380026">এর থেকে এক্সটেনশান লোড করতে ব্যর্থ হয়েছে:</translation>
 <translation id="5707604204219538797">পরবর্তী শব্দ </translation>
@@ -3450,7 +3445,6 @@
 <translation id="5900302528761731119">Google প্রোফাইল ফটো </translation>
 <translation id="5900623698597156974">একটি TLS 1.0 ফলব্যাক সার্ভারের সাথে হ্যান্ডশেক করতে সক্ষম হয়েছে, কিন্তু আমরা TLS 1.0 ফলব্যাক আর গ্রহণ করছি না। সংস্করণ সমঝোতাটি সঠিকভাবে কার্যকর করার জন্য সার্ভারকে আপডেট করতে হবে এবং সম্ভব হলে TLS 1.2 সমর্থন করার মত আপডেট করা প্রয়োজন।</translation>
 <translation id="590253956165195626">আপনি যে ভাষাতে পড়েন সেই ভাষাতে না থাকা পৃষ্ঠাগুলি অনুবাদ করার প্রস্তব দিন৷</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{১টি আইটেম}one{#টি আইটেম}other{#টি আইটেম}}</translation>
 <translation id="5904093760909470684">পক্সি কনফিগারেশন</translation>
 <translation id="5906065664303289925">হার্ডওয়্যার ঠিকানা:</translation>
 <translation id="5910363049092958439">এই রূপে চিত্র সং&amp;রক্ষণ করুন...</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb
index 9910df1..91d5417 100644
--- a/chrome/app/resources/generated_resources_ca.xtb
+++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Accedir a qualsevol d'aquests dispositius USB</translation>
 <translation id="1038168778161626396">Només encriptar</translation>
 <translation id="1038842779957582377">nom desconegut</translation>
-<translation id="1040931876666128942">Notificacions de WebUSB.</translation>
 <translation id="1042174272890264476">L'ordinador també incorpora la biblioteca RLZ de <ph name="SHORT_PRODUCT_NAME" />. La biblioteca RLZ assigna una etiqueta no única i sense identificació personal per mesurar les cerques i l'ús de <ph name="SHORT_PRODUCT_NAME" /> derivats d'una campanya promocional concreta. De vegades, aquestes etiquetes apareixen a les consultes de la Cerca de Google a <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> vol emmagatzemar una gran quantitat de dades al vostre dispositiu de manera permanent.</translation>
 <translation id="1045157690796831147">Transliteració (namaskar → നമസ്കാരം)</translation>
@@ -283,7 +282,7 @@
 <translation id="1407489512183974736">Retallat al centre</translation>
 <translation id="1408789165795197664">Configuració avançada...</translation>
 <translation id="1408803555324839240">No s'ha pogut crear l'usuari supervisat nou. Assegureu-vos que heu iniciat la sessió correctament i torneu-ho a provar.</translation>
-<translation id="1409390508152595145">Creeu un usuari supervisat</translation>
+<translation id="1409390508152595145">Crea un usuari supervisat</translation>
 <translation id="1410616244180625362">Continua permetent que <ph name="HOST" /> accedeixi a la càmera</translation>
 <translation id="1413372529771027206">El telèfon que utilitzeu per a Smart Lock ha canviat. Escriviu la contrasenya per actualitzar Smart Lock per a Chromebook en aquest dispositiu. La propera vegada només caldrà que feu clic a la imatge per accedir-hi.</translation>
 <translation id="1413809658975081374">Error de privadesa</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">La nova configuració de galetes es farà efectiva quan torneu a carregar la pàgina.</translation>
 <translation id="14720830734893704">Activa la compatibilitat del teclat virtual.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" no s'ha penjat. No hi ha prou espai lliure al vostre compte de Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 contrasenya}other{# contrasenyes}}</translation>
 <translation id="1476949146811612304">Definiu el motor de cerca que s'ha de fer servir en fer una cerca des de l'<ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Memòria cau del testimoni API d'identitat</translation>
 <translation id="1478340334823509079">Detalls: <ph name="FILE_NAME" /></translation>
@@ -923,6 +921,7 @@
 <translation id="2326606747676847821">Passa al mode d'incògnit</translation>
 <translation id="2326931316514688470">&amp;Tornar a carregar l'aplicació</translation>
 <translation id="2327492829706409234">Activa l'aplicació</translation>
+<translation id="2329597144923131178">Inicieu la sessió per tenir adreces d'interès, historial, contrasenyes i altres opcions de configuració en tots els dispositius.</translation>
 <translation id="2332131598580221120">Mostra a la botiga</translation>
 <translation id="2332742915001411729">Restableix als valors predeterminats</translation>
 <translation id="2335122562899522968">Aquesta pàgina emmagatzema galetes</translation>
@@ -946,7 +945,6 @@
 <translation id="2359808026110333948">Continua</translation>
 <translation id="236128817791440714">Opció recomanada: configuració de Smart Lock per a Android</translation>
 <translation id="236141728043665931">Bloqueja sempre l'accés al micròfon</translation>
-<translation id="2365626167708453863">Trieu un compte del vostre Google Smart Lock</translation>
 <translation id="2367972762794486313">Mostra les aplicacions</translation>
 <translation id="2368075211218459617">Habilita la cerca contextual.</translation>
 <translation id="2370882663124746154">Activa el mode pinyin doble</translation>
@@ -1536,7 +1534,7 @@
 <translation id="3160041952246459240">Teniu certificats arxivats que identifiquen els servidors següents:</translation>
 <translation id="316125635462764134">Suprimeix l'aplicació</translation>
 <translation id="3162559335345991374">És possible que la xarxa Wi-Fi que esteu fent servir requereixi que visiteu la seva pàgina d'inici de sessió.</translation>
-<translation id="316307797510303346">Controleu i consulteu els llocs web que aquesta persona visita des de <ph name="CUSTODIAN_EMAIL" />.
+<translation id="316307797510303346">Controla i consulta els llocs web que aquesta persona visita des de <ph name="CUSTODIAN_EMAIL" />.
     Les dades d'inici de sessió del compte no estan actualitzades.</translation>
 <translation id="3166571619128686629">Feu-hi clic o digueu "Ok Google" per començar la cerca per veu</translation>
 <translation id="3170072451822350649">També podeu <ph name="LINK_START" />navegar com a convidat<ph name="LINK_END" /> sense iniciar sessió.</translation>
@@ -2648,7 +2646,6 @@
 <translation id="4780374166989101364">Activa les API d'extensions experimentals. Tingueu en compte que la galeria d'extensions no permet penjar extensions que utilitzin API experimentals.</translation>
 <translation id="4781787911582943401">Apropa la pantalla</translation>
 <translation id="4782449893814226250">S'ha enviat una sol·licitud als pares per visitar aquesta pàgina.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Presentació de PowerPoint</translation>
 <translation id="4785040501822872973">Aquest equip es restablirà d'aquí a <ph name="LOGOUT_TIME_LEFT" /> segons.
 Premeu qualsevol tecla per continuar explorant.</translation>
@@ -3178,7 +3175,6 @@
 <translation id="5527474464531963247">També podeu seleccionar una altra xarxa.</translation>
 <translation id="5527963985407842218">Activeu el mode de lector</translation>
 <translation id="5528368756083817449">Gestor d'adreces d'interès</translation>
-<translation id="5529098031581368697"><ph name="APP_NAME" /> ha definit el fons de pantalla actual.</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">General</translation>
 <translation id="5533555070048896610">Transliteració (namaste → नमस्ते)</translation>
@@ -3295,7 +3291,6 @@
 <translation id="5702898740348134351">&amp;Edita els motors de cerca...</translation>
 <translation id="5703594190584829406">Mostra suggeriments d'emplenament automàtic a la part superior del teclat en comptes de mostrar-los en un menú desplegable.</translation>
 <translation id="5704272569086782895">Activar la rasterització de GPU per subprocessos.</translation>
-<translation id="570544101664452060">Notificacions experimentals de WebUSB.</translation>
 <translation id="5706551819490830015">Gestiona les adreces de facturació...</translation>
 <translation id="5707185214361380026">No s'ha pogut carregar l'extensió de:</translation>
 <translation id="5707604204219538797">Paraula següent</translation>
@@ -3387,7 +3382,7 @@
 <translation id="5830410401012830739">Gestiona la configuració de la ubicació...</translation>
 <translation id="5830720307094128296">Anomena i desa la pà&amp;gina...</translation>
 <translation id="5832669303303483065">Afegeix una adreça postal nova...</translation>
-<translation id="5832805196449965646">Afegiu una persona</translation>
+<translation id="5832805196449965646">Afegeix una persona</translation>
 <translation id="583281660410589416">Desconegut</translation>
 <translation id="5832830184511718549">Utilitza un subprocés secundari per crear pàgines web. Això permet un desplaçament suau, fins i tot quan el subprocés principal no respon.
 </translation>
@@ -3445,7 +3440,6 @@
 <translation id="5900302528761731119">Foto del perfil de Google</translation>
 <translation id="5900623698597156974">Una alternativa de TLS 1.0 ha pogut establir un protocol d'enllaç amb el servidor, però ja no acceptem alternatives de TLS 1.0. Cal actualitzar el servidor perquè s'hi implementi correctament la negociació de versions i sigui compatible, idealment, amb TLS 1.2.</translation>
 <translation id="590253956165195626">Proposa'm de traduir les pàgines escrites en un idioma que no entenc.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 element}other{# elements}}</translation>
 <translation id="5904093760909470684">Configuració del servidor intermediari</translation>
 <translation id="5906065664303289925">Adreça del maquinari:</translation>
 <translation id="5910363049092958439">De&amp;sa la imatge com a...</translation>
@@ -3463,7 +3457,7 @@
 <translation id="5934281776477898549">Cap actualització</translation>
 <translation id="5937843713457938680">Mode d'emmagatzematge en memòria cau per al motor V8 de JavaScript.</translation>
 <translation id="5939518447894949180">Restableix</translation>
-<translation id="5941153596444580863">Afegiu una persona...</translation>
+<translation id="5941153596444580863">Afegeix una persona...</translation>
 <translation id="5941343993301164315">Inicieu la sessió a <ph name="TOKEN_NAME" />.</translation>
 <translation id="5941711191222866238">Minimitza</translation>
 <translation id="5942207977017515242">https://support.google.com/chrome/?hl=<ph name="GRITLANGCODE_1" />&amp;p=settings_sign_in</translation>
@@ -3869,7 +3863,7 @@
 <translation id="655384502888039633"><ph name="USER_COUNT" /> usuaris</translation>
 <translation id="6555432686520421228">Suprimeix tots els comptes d'usuari i restableix el dispositiu <ph name="IDS_SHORT_PRODUCT_NAME" />, com si fos nou.</translation>
 <translation id="6556866813142980365">Refés</translation>
-<translation id="6557565812667414268">Activat només per a visualitzacions PPP d'alt rendiment</translation>
+<translation id="6557565812667414268">Activat només per a visualitzacions ppp d'alt rendiment</translation>
 <translation id="655845594391856372">La pestanya no respon. No es pot emetre contingut.</translation>
 <translation id="6559580823502247193">(ja és en aquest dispositiu)</translation>
 <translation id="6561726789132298588">retorn</translation>
@@ -4464,7 +4458,7 @@
 <translation id="7458128457147328975">Permet activar la versió obsoleta de les extensions multimèdia encriptades en elements d'àudio i de vídeo.</translation>
 <translation id="7460898608667578234">Ucraïnès</translation>
 <translation id="7461924472993315131">Fixa</translation>
-<translation id="7463006580194749499">Afegiu una persona</translation>
+<translation id="7463006580194749499">Afegeix una persona</translation>
 <translation id="7464490149090366184">S'ha produït un error en la compressió; l'element existeix: "$1"</translation>
 <translation id="7465778193084373987">URL de revocació de certificats de Netscape</translation>
 <translation id="7466861475611330213">Estil de puntuació</translation>
@@ -5696,7 +5690,7 @@
 <translation id="940425055435005472">Mida de la lletra:</translation>
 <translation id="941543339607623937">Clau privada no vàlida.</translation>
 <translation id="942954117721265519">No hi ha cap imatge en aquest directori.</translation>
-<translation id="945522503751344254">Envia comentaris</translation>
+<translation id="945522503751344254">Envia suggeriments</translation>
 <translation id="946810925362320585">Segueix la recomanació</translation>
 <translation id="949382280525592713"><ph name="LEGAL_DOC_AGREEMENT" /> Per protegir-vos de fraus, es compartirà informació sobre el vostre ordinador (inclosa la ubicació) amb Google Payments.</translation>
 <translation id="951981865514037445"><ph name="URL" /> vol fer servir la ubicació del dispositiu.</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb
index 4596649ad..340ba67 100644
--- a/chrome/app/resources/generated_resources_cs.xtb
+++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Přístup ke kterýmkoliv z těchto zařízení USB</translation>
 <translation id="1038168778161626396">Pouze šifrování</translation>
 <translation id="1038842779957582377">neznámé jméno</translation>
-<translation id="1040931876666128942">Oznámení WebUsb</translation>
 <translation id="1042174272890264476">Počítač je dodáván s integrovanou knihovnou RLZ prohlížeče <ph name="SHORT_PRODUCT_NAME" />. RLZ přiřadí značku, která slouží k vyhodnocení vyhledávání a využití prohlížečů <ph name="SHORT_PRODUCT_NAME" />, které pocházejí z konkrétní propagační kampaně. Tato značka není jedinečná a neumožňuje osobní identifikaci. Tyto značky jsou někdy v prohlížeči <ph name="PRODUCT_NAME" /> uváděny v dotazech ve Vyhledávání Google.</translation>
 <translation id="1042574203789536285">Stránka <ph name="URL" /> chce v zařízení trvale ukládat velké množství dat.</translation>
 <translation id="1045157690796831147">Přepis (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Nové nastavení souborů cookie se projeví po opětovném načtení stránky.</translation>
 <translation id="14720830734893704">Aktivuje podporu virtuální klávesnice.</translation>
 <translation id="1474339897586437869">Soubor <ph name="FILENAME" /> nelze nahrát. Na Disku Google je nedostatek místa.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 heslo}few{# hesla}many{# hesla}other{# hesel}}</translation>
 <translation id="1476949146811612304">Nastavit vyhledávač, který se používá při vyhledávání v
         <ph name="BEGIN_LINK" />omniboxu<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Mezipaměť tokenů rozhraní Identity API</translation>
@@ -920,6 +918,7 @@
 <translation id="2326606747676847821">Anonymní režim</translation>
 <translation id="2326931316514688470">Znovu načíst &amp;aplikaci</translation>
 <translation id="2327492829706409234">Aktivovat aplikaci</translation>
+<translation id="2329597144923131178">Přihlaste se a synchronizujte záložky, historii, hesla a další nastavení do všech svých zařízení.</translation>
 <translation id="2332131598580221120">Zobrazit v obchodu</translation>
 <translation id="2332742915001411729">Výchozí nastavení</translation>
 <translation id="2335122562899522968">Tato stránka nastavila soubory cookie.</translation>
@@ -943,7 +942,6 @@
 <translation id="2359808026110333948">Pokračovat</translation>
 <translation id="236128817791440714">Doporučujeme: Nastavte si funkci Smart Lock pro Android</translation>
 <translation id="236141728043665931">Vždy blokovat přístup k mikrofonu</translation>
-<translation id="2365626167708453863">Zvolte účet z funkce Google Smart Lock</translation>
 <translation id="2367972762794486313">Zobrazit aplikace</translation>
 <translation id="2368075211218459617">Aktivovat kontextové vyhledávání</translation>
 <translation id="2370882663124746154">Aktivovat režim Double-Pinyin</translation>
@@ -2645,7 +2643,6 @@
 <translation id="4780374166989101364">Umožňuje aktivovat experimentální rozhraní API rozšíření. Upozornění: Galerie rozšíření neumožňuje nahrávat rozšíření, která používají experimentální rozhraní API.</translation>
 <translation id="4781787911582943401">Přiblíží obrazovku</translation>
 <translation id="4782449893814226250">Požádali jste rodiče o povolení návštěvy této stránky.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}few{# kB}many{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Prezentace aplikace PowerPoint</translation>
 <translation id="4785040501822872973">Počítač se za <ph name="LOGOUT_TIME_LEFT" /> sekund restartuje.
 Chcete-li pokračovat v práci, stiskněte libovolnou klávesu.</translation>
@@ -3174,7 +3171,6 @@
 <translation id="5527474464531963247">Můžete také vybrat jinou síť</translation>
 <translation id="5527963985407842218">Aktivace režimu čtečky</translation>
 <translation id="5528368756083817449">Správce záložek</translation>
-<translation id="5529098031581368697">Aktuální tapetu nastavila aplikace <ph name="APP_NAME" /></translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Globální</translation>
 <translation id="5533555070048896610">Přepis (namaste → नमस्ते)</translation>
@@ -3290,7 +3286,6 @@
 <translation id="5702898740348134351">Upravit vyhl&amp;edávače...</translation>
 <translation id="5703594190584829406">Zobrazuje návrhy Automatického vyplňování nad klávesnicí (namísto rozbalovacího seznamu).</translation>
 <translation id="5704272569086782895">Aktivovat rastrování prostřednictvím GPU v podprocesu</translation>
-<translation id="570544101664452060">Experimentální Oznámení WebUsb</translation>
 <translation id="5706551819490830015">Spravovat fakturační adresy...</translation>
 <translation id="5707185214361380026">Načtení rozšíření z následujícího umístění se nezdařilo:</translation>
 <translation id="5707604204219538797">Další slovo</translation>
@@ -3440,7 +3435,6 @@
 <translation id="5900302528761731119">Profilová fotka Google</translation>
 <translation id="5900623698597156974">Záloha TLS 1.0 byla schopna komunikovat se serverem pomocí metody handshake, avšak zálohy TLS 1.0 již nepodporujeme. Server je nutné aktualizovat, aby v něm byla správně implementována komunikace podle verzí a aby pokud možno podporoval protokol TLS 1.2.</translation>
 <translation id="590253956165195626">Nabízet překlad stránek v jazycích, kterým byste nemuseli rozumět.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 položka}few{# položky}many{# položky}other{# položek}}</translation>
 <translation id="5904093760909470684">Nastavení proxy serveru</translation>
 <translation id="5906065664303289925">Hardwarová adresa:</translation>
 <translation id="5910363049092958439">Uložit o&amp;brázek jako...</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb
index 7a3d477..ac2f305 100644
--- a/chrome/app/resources/generated_resources_da.xtb
+++ b/chrome/app/resources/generated_resources_da.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Få adgang til alle disse USB-enheder</translation>
 <translation id="1038168778161626396">Kun omsætning til kode</translation>
 <translation id="1038842779957582377">ukendt navn</translation>
-<translation id="1040931876666128942">WebUsb-underretninger.</translation>
 <translation id="1042174272890264476">Computeren leveres også med <ph name="SHORT_PRODUCT_NAME" />s RLZ-samling indbygget. RLZ tildeler et ikke-unikt, ikke-personligt identificerbart tag til at måle søgninger og <ph name="SHORT_PRODUCT_NAME" />-brug, der er drevet af en bestemt kampagne. Disse etiketter vises nogle gange i Googles søgeforespørgsler i <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> vil gemme store datamængder permanent på din enhed.</translation>
 <translation id="1045157690796831147">Translitteration (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">De nye indstillinger for cookies træder i kraft, når siden genindlæses.</translation>
 <translation id="14720830734893704">Aktivér understøttelse af virtuelt tastatur.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" blev ikke uploadet. Der er ikke plads nok i Google Drev.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 adgangskode}one{# adgangskoder}other{# adgangskoder}}</translation>
 <translation id="1476949146811612304">Angiv, hvilken søgemaskine der skal bruges, når du søger via <ph name="BEGIN_LINK" />omnifeltet<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Tokencache for Identity API</translation>
 <translation id="1478340334823509079">Detaljer: <ph name="FILE_NAME" /></translation>
@@ -919,6 +917,7 @@
 <translation id="2326606747676847821">Vær inkognito</translation>
 <translation id="2326931316514688470">&amp;Genindlæs app</translation>
 <translation id="2327492829706409234">Aktivér app</translation>
+<translation id="2329597144923131178">Log ind for at hente bogmærker, historik, adgangskoder og andre indstillinger på alle dine enheder.</translation>
 <translation id="2332131598580221120">Vis i Webshop</translation>
 <translation id="2332742915001411729">Nulstil til standard</translation>
 <translation id="2335122562899522968">Denne side indstiller cookies.</translation>
@@ -942,7 +941,6 @@
 <translation id="2359808026110333948">Fortsæt</translation>
 <translation id="236128817791440714">Anbefalet: Konfigurer Smart Lock til Android</translation>
 <translation id="236141728043665931">Bloker altid mikrofonadgang</translation>
-<translation id="2365626167708453863">Vælg en konto fra din Google Smart Lock</translation>
 <translation id="2367972762794486313">Vis apps</translation>
 <translation id="2368075211218459617">Aktivér Kontekstuel søgning.</translation>
 <translation id="2370882663124746154">Aktiver tilstanden Dobbelt pinyin</translation>
@@ -1376,7 +1374,7 @@
 <translation id="2932883381142163287">Rapportér misbrug</translation>
 <translation id="2934522647674136521">Brug GPU til at rasterisere webindhold. Kræver flertrådet rasterisering.</translation>
 <translation id="2937174152333875430">Aktivér synkronisering af applisten</translation>
-<translation id="2938225289965773019">Åbn <ph name="PROTOCOL" />-links</translation>
+<translation id="2938225289965773019">Åbne <ph name="PROTOCOL" />-links</translation>
 <translation id="2938685643439809023">Mongolsk</translation>
 <translation id="2942290791863759244">Tysk NEO 2-tastatur</translation>
 <translation id="2943400156390503548">Slides</translation>
@@ -2658,7 +2656,6 @@
 <translation id="4780374166989101364">Aktiverer eksperimentelle udvidelses-API'er. Bemærk, at galleriet over udvidelser ikke tillader upload af udvidelser, der bruger eksperimentelle API'er.</translation>
 <translation id="4781787911582943401">Zoom ind på skærmen</translation>
 <translation id="4782449893814226250">Du har spurgt dine forældre, om det er i orden at besøge denne side.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}one{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint-præsentation</translation>
 <translation id="4785040501822872973">Denne computer nulstilles om <ph name="LOGOUT_TIME_LEFT" /> sekunder.
 Tryk på en vilkårlig tast for at fortsætte udforskningen.</translation>
@@ -3188,7 +3185,6 @@
 <translation id="5527474464531963247">Du kan også vælge et andet netværk.</translation>
 <translation id="5527963985407842218">Udløsning af Læser-tilstand</translation>
 <translation id="5528368756083817449">Bogmærkeadministrator</translation>
-<translation id="5529098031581368697">Den nuværende baggrund er angivet af "<ph name="APP_NAME" />"</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Translitteration (namaste → नमस्ते)</translation>
@@ -3304,7 +3300,6 @@
 <translation id="5702898740348134351">&amp;Rediger søgemaskiner...</translation>
 <translation id="5703594190584829406">Viser forslag til autofyld øverst på tastaturet i stedet for i en rullemenu.</translation>
 <translation id="5704272569086782895">Aktivér trådet GPU-rasterisering.</translation>
-<translation id="570544101664452060">Eksperimentelle WebUsb-underretninger.</translation>
 <translation id="5706551819490830015">Administrer faktureringsadresser...</translation>
 <translation id="5707185214361380026">Det var ikke muligt at indlæse udvidelsen fra:</translation>
 <translation id="5707604204219538797">Næste ord</translation>
@@ -3453,7 +3448,6 @@
 <translation id="5900302528761731119">Google-profilbillede</translation>
 <translation id="5900623698597156974">Et TLS 1.0-alternativ kunne udveksle data med serveren. Vi accepterer dog ikke længere TLS 1.0-alternativer. Serveren skal opdateres, før den kan implementere versionsforhandling korrekt og så vidt muligt understøtte TLS 1.2.</translation>
 <translation id="590253956165195626">Tilbyd at oversætte sider, der ikke er på et sprog, du kan læse.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 element}one{# elementer}other{# elementer}}</translation>
 <translation id="5904093760909470684">Proxykonfiguration</translation>
 <translation id="5906065664303289925">Hardwareadresse:</translation>
 <translation id="5910363049092958439">Ge&amp;m billede som...</translation>
@@ -3587,7 +3581,7 @@
 <translation id="6102473941787693058">Aktivér tilvalg af rapportering af ugyldige TLS/SSL-certifikatkæder</translation>
 <translation id="6102988872254107946">Selvom du har besøgt dette website før, er det ikke sikkert lige nu. Google Beskyttet browsing <ph name="BEGIN_LINK" />registrerede malware<ph name="END_LINK" /> på <ph name="SITE" /> for nylig. Websites, der normalt er sikre, inficeres undertiden med malware.</translation>
 <translation id="6103681770816982672">Advarsel! Du er ved at skifte til udviklerkanal</translation>
-<translation id="6105158702728922449">Brug dit kamera og din mikrofon</translation>
+<translation id="6105158702728922449">Bruge dit kamera og din mikrofon</translation>
 <translation id="6105366316359454748">En proxyserver er en server, der agerer som et mellemled mellem din enhed og andre servere. Dit system er nu konfigureret til brug som proxy, men
           <ph name="PRODUCT_NAME" />
           kan ikke oprette forbindelse til det.</translation>
@@ -4309,7 +4303,7 @@
 <translation id="7219179957768738017">Forbindelsen bruger <ph name="SSL_VERSION" />.</translation>
 <translation id="7219357088166514551">Søg på <ph name="ENGINE" />, eller indtast webadressen</translation>
 <translation id="7221155467930685510">$1 GB</translation>
-<translation id="7221855153210829124">Vis underretninger</translation>
+<translation id="7221855153210829124">Vise underretninger</translation>
 <translation id="7221869452894271364">Genindlæs denne side</translation>
 <translation id="7222232353993864120">E-mailadresse</translation>
 <translation id="7222245588540287464">Uanset om Kontekstuel søgning er aktiveret.</translation>
@@ -4615,7 +4609,7 @@
 <translation id="7646821968331713409">Antallet af rastertråde</translation>
 <translation id="7648048654005891115">Tastaturoversigt</translation>
 <translation id="7648595706644580203">Bevægelsesredigering på det virtuelle tastatur.</translation>
-<translation id="7648992873808071793">Gem filer på denne enhed</translation>
+<translation id="7648992873808071793">Gemme filer på denne enhed</translation>
 <translation id="7649070708921625228">Hjælp</translation>
 <translation id="7650511557061837441">"<ph name="TRIGGERING_EXTENSION_NAME" />" vil gerne fjerne "<ph name="EXTENSION_NAME" />".</translation>
 <translation id="7650701856438921772"><ph name="PRODUCT_NAME" /> vises på dette sprog</translation>
@@ -5375,7 +5369,7 @@
 <translation id="8734073480934656039">Ved at aktivere denne indstilling tillader du, at terminalapplikationer åbnes automatisk under opstart.</translation>
 <translation id="8736288397686080465">Dette website er blevet opdateret i baggrunden.</translation>
 <translation id="8737260648576902897">Installer Adobe Reader</translation>
-<translation id="8737685506611670901">Åbn <ph name="PROTOCOL" />-links i stedet for <ph name="REPLACED_HANDLER_TITLE" /></translation>
+<translation id="8737685506611670901">Åbne <ph name="PROTOCOL" />-links i stedet for <ph name="REPLACED_HANDLER_TITLE" /></translation>
 <translation id="8737709691285775803">Shill</translation>
 <translation id="87377425248837826">Aktiver paneler</translation>
 <translation id="874420130893181774">Traditionel Pinyin-indtastningsmetode</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb
index d99ad09..561612c 100644
--- a/chrome/app/resources/generated_resources_de.xtb
+++ b/chrome/app/resources/generated_resources_de.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Auf alle diese USB-Geräte zugreifen</translation>
 <translation id="1038168778161626396">Nur verschlüsseln</translation>
 <translation id="1038842779957582377">Unbekannter Name</translation>
-<translation id="1040931876666128942">WebUsb-Benachrichtigungen.</translation>
 <translation id="1042174272890264476">Auch die RLZ-Bibliothek von <ph name="SHORT_PRODUCT_NAME" /> ist auf Ihrem Computer vorinstalliert. RLZ sorgt für die Zuweisung von Tags, anhand derer gemessen wird, wie sich einzelne Werbekampagnen auf die Suchanfragen und die Nutzung von <ph name="SHORT_PRODUCT_NAME" /> auswirken. Die Tags sind weder eindeutig, noch personenbezogen und kommen manchmal in Google-Suchanfragen in <ph name="PRODUCT_NAME" /> vor.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> möchte dauerhaft umfangreiche Daten auf Ihrem Gerät speichern.</translation>
 <translation id="1045157690796831147">Transliteration (namaskar → നമസ്കാരം)</translation>
@@ -326,7 +325,6 @@
 <translation id="1470719357688513792">Neue Cookie-Einstellungen werden nach erneutem Laden der Seite wirksam.</translation>
 <translation id="14720830734893704">Aktiviert die Unterstützung für die Bildschirmtastatur.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" konnte nicht hochgeladen werden. In Ihrem Google Drive-Konto ist nicht genügend Speicherplatz frei.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 Passwort}other{# Passwörter}}</translation>
 <translation id="1476949146811612304">Legen Sie fest, welche Suchmaschine bei einer Suche über die <ph name="BEGIN_LINK" />Omnibox<ph name="END_LINK" /> verwendet werden soll.</translation>
 <translation id="1477301030751268706">Token-Cache für die Identity API</translation>
 <translation id="1478340334823509079">Details: <ph name="FILE_NAME" /></translation>
@@ -914,6 +912,7 @@
 <translation id="2326606747676847821">Zum Inkognitomodus wechseln</translation>
 <translation id="2326931316514688470">App &amp;neu laden</translation>
 <translation id="2327492829706409234">App aktivieren</translation>
+<translation id="2329597144923131178">Melden Sie sich an, um Ihre Lesezeichen, Ihren Verlauf, Ihre Passwörter und andere Einstellungen auf allen Ihren Geräten aufzurufen.</translation>
 <translation id="2332131598580221120">Im Store ansehen</translation>
 <translation id="2332742915001411729">Auf Standardeinstellungen zurücksetzen</translation>
 <translation id="2335122562899522968">Diese Seite hat Cookies gesetzt.</translation>
@@ -937,7 +936,6 @@
 <translation id="2359808026110333948">Weiter</translation>
 <translation id="236128817791440714">Empfehlung: Smart Lock für Android einrichten</translation>
 <translation id="236141728043665931">Zugriff auf das Mikrofon immer blockieren</translation>
-<translation id="2365626167708453863">Konto aus Google Smart Lock auswählen</translation>
 <translation id="2367972762794486313">Apps anzeigen</translation>
 <translation id="2368075211218459617">Kontextsuche aktivieren</translation>
 <translation id="2370882663124746154">Double-Pinyin-Modus aktivieren</translation>
@@ -2648,7 +2646,6 @@
 <translation id="4780374166989101364">Aktiviert experimentelle Erweiterungs-APIs. Beachten Sie, dass Sie in die Erweiterungsgalerie keine Erweiterungen hochladen können, die experimentelle APIs verwenden.</translation>
 <translation id="4781787911582943401">Bildschirm heranzoomen</translation>
 <translation id="4782449893814226250">Du hast deine Eltern gefragt, ob du diese Seite besuchen darfst.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}other{# KB}}</translation>
 <translation id="4784330909746505604">PowerPoint-Präsentation</translation>
 <translation id="4785040501822872973">Dieser Computer wird in <ph name="LOGOUT_TIME_LEFT" /> Sekunden zurückgesetzt.
 Drücken Sie eine beliebige Taste, um fortzufahren.</translation>
@@ -3177,7 +3174,6 @@
 <translation id="5527474464531963247">Sie können auch ein anderes Netzwerk auswählen.</translation>
 <translation id="5527963985407842218">Aktivierung des Lesemodus</translation>
 <translation id="5528368756083817449">Lesezeichenmanager</translation>
-<translation id="5529098031581368697">Der aktuelle Hintergrund wurde von "<ph name="APP_NAME" />" festgelegt.</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Transliteration (namaste → नमस्ते)</translation>
@@ -3293,7 +3289,6 @@
 <translation id="5702898740348134351">Suchmaschin&amp;en bearbeiten...</translation>
 <translation id="5703594190584829406">AutoFill-Vorschläge werden über der Tastatur statt in einem Drop-down-Menü angezeigt.</translation>
 <translation id="5704272569086782895">GPU-Rasterung mit Threads aktivieren</translation>
-<translation id="570544101664452060">Experimentelle WebUsb-Benachrichtigungen.</translation>
 <translation id="5706551819490830015">Rechnungsadressen verwalten...</translation>
 <translation id="5707185214361380026">Fehler beim Laden der Erweiterung aus:</translation>
 <translation id="5707604204219538797">Nächstes Wort</translation>
@@ -3438,7 +3433,6 @@
 <translation id="5900302528761731119">Google Profile-Foto</translation>
 <translation id="5900623698597156974">Ein TLS-1.0-Fallback konnte einen Handshake mit dem Server durchführen, TLS-1.0-Fallbacks werden jedoch nicht mehr akzeptiert. Der Server muss aktualisiert werden, um die Versionsaushandlung korrekt zu implementieren, und sollte vorzugsweise TLS 1.2 unterstützen.</translation>
 <translation id="590253956165195626">Übersetzung von fremdsprachigen Seiten anbieten</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 Eintrag}other{# Einträge}}</translation>
 <translation id="5904093760909470684">Konfiguration</translation>
 <translation id="5906065664303289925">Hardware-Adresse:</translation>
 <translation id="5910363049092958439">Bi&amp;ld speichern unter...</translation>
@@ -5147,7 +5141,7 @@
 <translation id="8452588990572106089">Ungültige Kartennummer. Bitte überprüfen Sie Ihre Angaben und versuchen Sie es erneut.</translation>
 <translation id="8453482423012550001">$1-Elemente werden kopiert...</translation>
 <translation id="8454189779191516805">Gibt die Anzahl an MSAA-Beispielen für die GPU-Rasterung an</translation>
-<translation id="8454288007744638700">Sie können auch ein anderes Netzwerk auswählen.</translation>
+<translation id="8454288007744638700">Sie können auch ein anderes Netzwerk auswählen:</translation>
 <translation id="845627346958584683">Ablaufzeit</translation>
 <translation id="8456681095658380701">Ungültiger Name</translation>
 <translation id="8457625695411745683">gut</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb
index eea2514..2ceeac2 100644
--- a/chrome/app/resources/generated_resources_el.xtb
+++ b/chrome/app/resources/generated_resources_el.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Πρόσβαση σε οποιαδήποτε από αυτές τις συσκευές USB</translation>
 <translation id="1038168778161626396">Μόνο κρυπτογράφηση</translation>
 <translation id="1038842779957582377">άγνωστο όνομα</translation>
-<translation id="1040931876666128942">Ειδοποιήσεις WebUsb.</translation>
 <translation id="1042174272890264476">Ο υπολογιστής σας κυκλοφορεί και με ενσωματωμένη τη βιβλιοθήκη RLZ του <ph name="SHORT_PRODUCT_NAME" />. Το RLZ εκχωρεί μια μη μοναδική ετικέτα μη προσωπικής ταυτοποίησης για τη μέτρηση των αναζητήσεων και της χρήσης του <ph name="SHORT_PRODUCT_NAME" /> που προκύπτει από μια συγκεκριμένη καμπάνια προώθησης. Αυτές οι ετικέτες εμφανίζονται μερικές φορές σε ερωτήματα στην Αναζήτηση Google στο <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285">Ο ιστότοπος <ph name="URL" /> θέλει να αποθηκεύσει μόνιμα δεδομένα μεγάλου όγκου στη συσκευή σας.</translation>
 <translation id="1045157690796831147">Μεταγραφή (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">Οι ρυθμίσεις νέων cookie θα εφαρμοστούν μετά την επανάληψη φόρτωσης της σελίδας.</translation>
 <translation id="14720830734893704">Ενεργοποίηση υποστήριξης εικονικού πληκτρολογίου.</translation>
 <translation id="1474339897586437869">Το αρχείο "<ph name="FILENAME" />" δεν ανέβηκε. Δεν υπάρχει επαρκής ελεύθερος χώρος στο Google Drive σας.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 κωδικός πρόσβασης}other{# κωδικοί πρόσβασης}}</translation>
 <translation id="1476949146811612304">Ορίστε ποια μηχανή αναζήτησης θα χρησιμοποιείται κατά την αναζήτηση από το
         <ph name="BEGIN_LINK" />κύριο πλαίσιο<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Κρυφή μνήμη διακριτικών API ταυτότητας</translation>
@@ -926,6 +924,7 @@
 <translation id="2326606747676847821">Ανώνυμη περιήγηση</translation>
 <translation id="2326931316514688470">Ε&amp;πανάληψη φόρτωσης εφαρμογής</translation>
 <translation id="2327492829706409234">Ενεργοποίηση εφαρμογής</translation>
+<translation id="2329597144923131178">Συνδεθείτε για χρήση σελιδοδεικτών, ιστορικού, κωδ.πρόσβ. κ.λπ. σε όλες τις συσκευές.</translation>
 <translation id="2332131598580221120">Προβολή στο Web Store</translation>
 <translation id="2332742915001411729">Επαναφορά προεπιλογής</translation>
 <translation id="2335122562899522968">Αυτή η σελίδα έχει ορίσει cookie.</translation>
@@ -949,7 +948,6 @@
 <translation id="2359808026110333948">Συνέχεια</translation>
 <translation id="236128817791440714">Συνιστάται: Ρύθμιση της λειτουργίας Smart Lock για Android</translation>
 <translation id="236141728043665931">Να μην επιτρέπται ποτέ η πρόσβαση στο μικρόφωνο</translation>
-<translation id="2365626167708453863">Επιλέξτε έναν λογαριασμό από το Google Smart Lock</translation>
 <translation id="2367972762794486313">Εμφάνιση εφαρμογών</translation>
 <translation id="2368075211218459617">Ενεργοποίηση Αναζήτησης με βάση τα συμφραζόμενα.</translation>
 <translation id="2370882663124746154">Ενεργοποίηση λειτουργίας Double-Pinyin</translation>
@@ -2672,7 +2670,6 @@
 <translation id="4780374166989101364">Ενεργοποιεί τα πειραματικά API επεκτάσεων. Λάβετε υπόψη ότι η συλλογή επεκτάσεων δεν σας δίνει τη δυνατότητα να ανεβάσετε επεκτάσεις που χρησιμοποιούν πειραματικά API.</translation>
 <translation id="4781787911582943401">Μεγέθυνση οθόνης</translation>
 <translation id="4782449893814226250">Ρώτησες τους γονείς σου εάν σου επιτρέπουν να επισκεφτείς αυτήν τη σελίδα.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Παρουσίαση PowerPoint</translation>
 <translation id="4785040501822872973">Θα γίνει επαναφορά αυτού του υπολογιστή σε <ph name="LOGOUT_TIME_LEFT" /> δευτερόλεπτα.
 Πατήστε οποιοδήποτε πλήκτρο για να συνεχίσετε την εξερεύνηση.</translation>
@@ -3207,7 +3204,6 @@
 <translation id="5527474464531963247">Μπορείτε επίσης να επιλέξετε άλλο δίκτυο.</translation>
 <translation id="5527963985407842218">Ενεργοποίηση κουμπιού λειτουργίας ανάγνωσης</translation>
 <translation id="5528368756083817449">Διαχείριση σελιδοδεικτών</translation>
-<translation id="5529098031581368697">Η τρέχουσα ταπετσαρία έχει οριστεί από την εφαρμογή "<ph name="APP_NAME" />"</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Γενικές</translation>
 <translation id="5533555070048896610">Μεταγραφή (namaste → नमस्ते)</translation>
@@ -3324,7 +3320,6 @@
 <translation id="5702898740348134351">&amp;Επεξεργασία μηχανών αναζήτησης...</translation>
 <translation id="5703594190584829406">Δείχνει προτάσεις Αυτόματης συμπλήρωσης στο επάνω μέρος του πληκτρολογίου και όχι σε αναπτυσσόμενο παράθυρο.</translation>
 <translation id="5704272569086782895">Ενεργοποίηση εφαρμογής raster GPU με νήμα.</translation>
-<translation id="570544101664452060">Πειραματικές ειδοποιήσεις WebUsb.</translation>
 <translation id="5706551819490830015">Διαχείριση διευθύνσεων χρέωσης…</translation>
 <translation id="5707185214361380026">Αποτυχία φόρτωσης επέκτασης από:</translation>
 <translation id="5707604204219538797">Επόμενη λέξη</translation>
@@ -3473,7 +3468,6 @@
 <translation id="5900302528761731119">Φωτογραφία προφίλ Google</translation>
 <translation id="5900623698597156974">Ένα εναλλακτικό πρότυπο TLS 1.0 κατάφερε να επικοινωνήσει με το διακομιστή, αλλά δεν γίνονται πλέον αποδεκτά εναλλακτικά πρότυπα TLS 1.0. Ο διακομιστής πρέπει να ενημερωθεί ώστε να εφαρμόσει σωστά τη διαπραγμάτευση έκδοσης και κατά προτίμηση το πρότυπο TLS 1.2.</translation>
 <translation id="590253956165195626">Να προτείνεται να μεταφράζονται οι σελίδες που δεν εμφανίζονται στη γλώσσα ανάγνωσής σας.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 στοιχείο}other{# στοιχεία}}</translation>
 <translation id="5904093760909470684">Διαμόρφωση διακομιστή μεσολάβησης</translation>
 <translation id="5906065664303289925">Διεύθυνση υλικού:</translation>
 <translation id="5910363049092958439">Απο&amp;θήκευση Εικόνας Ως...</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb
index ce18b70f..2fe378b 100644
--- a/chrome/app/resources/generated_resources_en-GB.xtb
+++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Access any of these USB devices</translation>
 <translation id="1038168778161626396">Encipher Only</translation>
 <translation id="1038842779957582377">unknown name</translation>
-<translation id="1040931876666128942">WebUsb notifications.</translation>
 <translation id="1042174272890264476">Your computer also comes with <ph name="SHORT_PRODUCT_NAME" />'s RLZ library built in. RLZ assigns a non-unique, non-personally identifiable tag to measure the searches and <ph name="SHORT_PRODUCT_NAME" /> usage driven by a particular promotional campaign. These labels sometimes appear in Google Search queries in <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> wants to permanently store large data on your device.</translation>
 <translation id="1045157690796831147">Transliteration (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">New cookie settings will take effect after reloading the page.</translation>
 <translation id="14720830734893704">Enable virtual keyboard support.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" was not uploaded. There is not enough free space in your Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 password}other{# passwords}}</translation>
 <translation id="1476949146811612304">Set which search engine is used when searching from the
         <ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Identity API Token Cache</translation>
@@ -925,6 +923,7 @@
 <translation id="2326606747676847821">Go incognito</translation>
 <translation id="2326931316514688470">&amp;Reload app</translation>
 <translation id="2327492829706409234">Enable app</translation>
+<translation id="2329597144923131178">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation>
 <translation id="2332131598580221120">View in store</translation>
 <translation id="2332742915001411729">Reset to default</translation>
 <translation id="2335122562899522968">This page has set cookies.</translation>
@@ -948,7 +947,6 @@
 <translation id="2359808026110333948">Continue</translation>
 <translation id="236128817791440714">Recommended: Set up Smart Lock for Android</translation>
 <translation id="236141728043665931">Always block microphone access</translation>
-<translation id="2365626167708453863">Choose an account from your Google Smart Lock</translation>
 <translation id="2367972762794486313">Show apps</translation>
 <translation id="2368075211218459617">Enable Contextual Search.</translation>
 <translation id="2370882663124746154">Enable Double-Pinyin mode</translation>
@@ -2664,7 +2662,6 @@
 <translation id="4780374166989101364">Enables experimental extension APIs. Note that the extension gallery doesn't allow you to upload extensions that use experimental APIs.</translation>
 <translation id="4781787911582943401">Zoom screen in</translation>
 <translation id="4782449893814226250">You asked your parents if it's OK to visit this page.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint presentation</translation>
 <translation id="4785040501822872973">This computer will reset in <ph name="LOGOUT_TIME_LEFT" /> seconds.
 Press any key to continue exploring.</translation>
@@ -3195,7 +3192,6 @@
 <translation id="5527474464531963247">You may also select another network.</translation>
 <translation id="5527963985407842218">Reader Mode triggering</translation>
 <translation id="5528368756083817449">Bookmark Manager</translation>
-<translation id="5529098031581368697">Current wallpaper is set by '<ph name="APP_NAME" />'</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Transliteration (namaste → नमस्ते)</translation>
@@ -3311,7 +3307,6 @@
 <translation id="5702898740348134351">&amp;Edit Search Engines...</translation>
 <translation id="5703594190584829406">Shows auto-fill suggestions on top of the keyboard rather than in a dropdown.</translation>
 <translation id="5704272569086782895">Enable threaded GPU rasterisation.</translation>
-<translation id="570544101664452060">Experimental WebUsb notifications.</translation>
 <translation id="5706551819490830015">Manage billing addresses...</translation>
 <translation id="5707185214361380026">Failed to load extension from:</translation>
 <translation id="5707604204219538797">Next word</translation>
@@ -3460,7 +3455,6 @@
 <translation id="5900302528761731119">Google Profile photo</translation>
 <translation id="5900623698597156974">A TLS 1.0 fallback was able to handshake with the server, but we no longer accept TLS 1.0 fallbacks. The server needs to be updated to correctly implement version negotiation and preferably support TLS 1.2.</translation>
 <translation id="590253956165195626">Offer to translate pages that aren't in a language you read.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 item}other{# items}}</translation>
 <translation id="5904093760909470684">Proxy Configuration</translation>
 <translation id="5906065664303289925">Hardware address:</translation>
 <translation id="5910363049092958439">Sa&amp;ve Image As...</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb
index be056495..01f56ce 100644
--- a/chrome/app/resources/generated_resources_es-419.xtb
+++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Acceder a cualquiera de estos dispositivos USB</translation>
 <translation id="1038168778161626396">Sólo cifrar</translation>
 <translation id="1038842779957582377">nombre desconocido</translation>
-<translation id="1040931876666128942">Notificaciones de WebUsb.</translation>
 <translation id="1042174272890264476">Tu computadora también tiene la biblioteca RLZ de <ph name="SHORT_PRODUCT_NAME" /> incorporada. RLZ asigna una etiqueta identificable, no exclusiva y no personal para medir las búsquedas y el uso de <ph name="SHORT_PRODUCT_NAME" /> impulsados por una determinada campaña de promoción. Estas etiquetas aparecen a veces en las consultas de la Búsqueda de Google en <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> quiere almacenar datos de gran tamaño de forma permanente en tu dispositivo.</translation>
 <translation id="1045157690796831147">Transliteración (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">La nueva configuración de cookie se hará efectiva cuando vuelvas a cargar la página.</translation>
 <translation id="14720830734893704">Permite habilitar la compatibilidad con el teclado virtual.</translation>
 <translation id="1474339897586437869">No se cargó "<ph name="FILENAME" />". No hay suficiente espacio libre en Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 contraseña}other{# contraseñas}}</translation>
 <translation id="1476949146811612304">Establece el motor de búsqueda que se utiliza cuando se realiza una búsqueda en el <ph name="BEGIN_LINK" />cuadro multifunción<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Caché del token de la API de identidad</translation>
 <translation id="1478340334823509079">Detalles: <ph name="FILE_NAME" /></translation>
@@ -919,6 +917,7 @@
 <translation id="2326606747676847821">Modo de navegación de incógnito</translation>
 <translation id="2326931316514688470">&amp;Volver a cargar la aplicación</translation>
 <translation id="2327492829706409234">Habilitar aplicación</translation>
+<translation id="2329597144923131178">Accede a tu cuenta para ver los marcadores, el historial, las contraseñas y otras opciones de configuración en todos los dispositivos.</translation>
 <translation id="2332131598580221120">Ver en Chrome Web Store</translation>
 <translation id="2332742915001411729">Restablecer configuración de zoom predeterminada</translation>
 <translation id="2335122562899522968">Esta página establece cookies.</translation>
@@ -942,7 +941,6 @@
 <translation id="2359808026110333948">Continuar</translation>
 <translation id="236128817791440714">Recomendado: configurar Smart Lock para Android</translation>
 <translation id="236141728043665931">Bloquear siempre el acceso al micrófono</translation>
-<translation id="2365626167708453863">Selecciona una cuenta desde tu Google Smart Lock.</translation>
 <translation id="2367972762794486313">Mostrar aplicaciones</translation>
 <translation id="2368075211218459617">Habilitar búsqueda contextual</translation>
 <translation id="2370882663124746154">Habilitar modo Doble pinyin</translation>
@@ -2651,7 +2649,6 @@
 <translation id="4780374166989101364">Habilita una extensión experimental API. Nota que la galería de extensión no te permite cargar extensiones que usen las API experimentales.</translation>
 <translation id="4781787911582943401">Acercar pantalla</translation>
 <translation id="4782449893814226250">Les preguntaste a tus padres si puedes visitar esta página.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 Kb}other{# Kb}}</translation>
 <translation id="4784330909746505604">Presentación de PowerPoint</translation>
 <translation id="4785040501822872973">Esta computadora se reiniciará en <ph name="LOGOUT_TIME_LEFT" /> segundos.
 Presiona cualquier tecla para seguir con navegando.</translation>
@@ -3182,7 +3179,6 @@
 <translation id="5527474464531963247">También puedes seleccionar otra red.</translation>
 <translation id="5527963985407842218">Activación del modo de lectura</translation>
 <translation id="5528368756083817449">Administrador de marcadores</translation>
-<translation id="5529098031581368697">"<ph name="APP_NAME" />" estableció el fondo de pantalla actual.</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Transliteración (namaste → नमस्ते)</translation>
@@ -3298,7 +3294,6 @@
 <translation id="5702898740348134351">&amp;Modificar los motores de búsqueda...</translation>
 <translation id="5703594190584829406">Muestra las sugerencias de Autocompletar sobre el teclado en lugar de una lista desplegable.</translation>
 <translation id="5704272569086782895">Habilitar rasterización por subprocesos de GPU</translation>
-<translation id="570544101664452060">Notificaciones de WebUsb experimentales.</translation>
 <translation id="5706551819490830015">Administrar direcciones de facturación...</translation>
 <translation id="5707185214361380026">Error al cargar la extensión desde:</translation>
 <translation id="5707604204219538797">Siguiente palabra</translation>
@@ -3448,7 +3443,6 @@
 <translation id="5900302528761731119">Foto de perfil de Google</translation>
 <translation id="5900623698597156974">Un resguardo TLS 1.0 pudo establecer un protocolo de enlace con el servidor, pero ya no aceptamos resguardos TLS 1.0. El servidor debe actualizarse para implementar correctamente la negociación de versión y admitir preferiblemente TLS 1.2.</translation>
 <translation id="590253956165195626">Preguntarme si quiero traducir páginas que no estén en un idioma que puedo leer</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 elemento}other{# elementos}}</translation>
 <translation id="5904093760909470684">Configuración de proxy</translation>
 <translation id="5906065664303289925">Dirección de hardware:</translation>
 <translation id="5910363049092958439">Gu&amp;ardar imagen como...</translation>
@@ -5168,7 +5162,7 @@
 <translation id="8452588990572106089">El número de tarjeta no es válido. Compruébalo y vuelve a intentarlo.</translation>
 <translation id="8453482423012550001">Copiando $1 elementos…</translation>
 <translation id="8454189779191516805">Especifica el número de muestras de MSAA correspondientes a la rasterización de la GPU.</translation>
-<translation id="8454288007744638700">O bien, seleccionar una nueva red:</translation>
+<translation id="8454288007744638700">O bien, selecciona una nueva red:</translation>
 <translation id="845627346958584683">Hora de vencimiento</translation>
 <translation id="8456681095658380701">Nombre no válido</translation>
 <translation id="8457625695411745683">buena</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb
index 97760b0e..1347826e 100644
--- a/chrome/app/resources/generated_resources_es.xtb
+++ b/chrome/app/resources/generated_resources_es.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Acceder a cualquiera de estos dispositivos USB</translation>
 <translation id="1038168778161626396">Solo cifrar</translation>
 <translation id="1038842779957582377">nombre desconocido</translation>
-<translation id="1040931876666128942">Notificaciones de WebUsb.</translation>
 <translation id="1042174272890264476">El ordenador también incluye la biblioteca RLZ de <ph name="SHORT_PRODUCT_NAME" />. RLZ asigna una etiqueta identificable, no exclusiva y no personal para medir las búsquedas y el uso de <ph name="SHORT_PRODUCT_NAME" /> derivados de una determinada campaña promocional. Estas etiquetas aparecen a veces en las consultas de la Búsqueda de Google realizadas en <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> quiere almacenar datos de gran tamaño de forma permanente en tu dispositivo.</translation>
 <translation id="1045157690796831147">Transliteración (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">La nueva configuración de cookies se aplicará al volver a cargar la página.</translation>
 <translation id="14720830734893704">Permite habilitar el uso del teclado virtual.</translation>
 <translation id="1474339897586437869">No se ha subido <ph name="FILENAME" />. No hay suficiente espacio libre en tu cuenta de Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 contraseña}other{# contraseñas}}</translation>
 <translation id="1476949146811612304">Especifica el motor de búsqueda que se debe utilizar al realizar una búsqueda desde el <ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Caché del token de la API de identidad</translation>
 <translation id="1478340334823509079">Detalles: <ph name="FILE_NAME" /></translation>
@@ -924,6 +922,7 @@
 <translation id="2326606747676847821">Navegar de incógnito</translation>
 <translation id="2326931316514688470">&amp;Volver a cargar aplicación</translation>
 <translation id="2327492829706409234">Habilitar aplicación</translation>
+<translation id="2329597144923131178">Accede para ver marcadores, historial, contraseñas y otros en dispos.</translation>
 <translation id="2332131598580221120">Ver en Chrome Web Store</translation>
 <translation id="2332742915001411729">Restablecer nivel de zoom predeterminado</translation>
 <translation id="2335122562899522968">Esta página almacena cookies</translation>
@@ -947,7 +946,6 @@
 <translation id="2359808026110333948">Continuar</translation>
 <translation id="236128817791440714">Recomendado: configurar Smart Lock para Android</translation>
 <translation id="236141728043665931">Bloquear siempre el acceso al micrófono</translation>
-<translation id="2365626167708453863">Selecciona una cuenta desde tu Google Smart Lock</translation>
 <translation id="2367972762794486313">Mostrar aplicaciones</translation>
 <translation id="2368075211218459617">Habilitar la búsqueda contextual.</translation>
 <translation id="2370882663124746154">Habilitar el modo pinyin de doble entrada</translation>
@@ -2656,7 +2654,6 @@
 <translation id="4780374166989101364">Habilita las API de extensiones experimentales. Ten en cuenta que la galería de extensiones no permite subir extensiones que utilicen API experimentales.</translation>
 <translation id="4781787911582943401">Ampliar pantalla</translation>
 <translation id="4782449893814226250">Has solicitado permiso a tus padres para poder acceder a esta página.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Presentación de PowerPoint</translation>
 <translation id="4785040501822872973">Este ordenador se reiniciará en <ph name="LOGOUT_TIME_LEFT" /> segundos.
 Pulsa cualquier tecla para seguir con la exploración.</translation>
@@ -3184,7 +3181,6 @@
 <translation id="5527474464531963247">También puedes seleccionar otra red.</translation>
 <translation id="5527963985407842218">Activación del modo de lectura</translation>
 <translation id="5528368756083817449">Administrador de marcadores</translation>
-<translation id="5529098031581368697"><ph name="APP_NAME" /> ha establecido el fondo de pantalla actual</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Transliteración (namaste → नमस्ते)</translation>
@@ -3300,7 +3296,6 @@
 <translation id="5702898740348134351">&amp;Editar motores de búsqueda...</translation>
 <translation id="5703594190584829406">Muestra sugerencias de Autocompletar sobre el teclado en lugar de en una lista desplegable.</translation>
 <translation id="5704272569086782895">Habilitar la rasterización de GPU por subprocesos.</translation>
-<translation id="570544101664452060">Notificaciones de WebUsb experimentales.</translation>
 <translation id="5706551819490830015">Administrar direcciones de facturación...</translation>
 <translation id="5707185214361380026">Error al cargar la extensión desde:</translation>
 <translation id="5707604204219538797">Siguiente palabra</translation>
@@ -3355,7 +3350,7 @@
 <translation id="5771816112378578655">Configuración en curso...</translation>
 <translation id="5771849619911534867">Búsqueda de dispositivos detenida.</translation>
 <translation id="5772177959740802111">Compatibilidad de Chromecast experimental con el reproductor de vídeo</translation>
-<translation id="5774295353725270860">Aplicación para abrir archivos</translation>
+<translation id="5774295353725270860">Abrir la aplicación Archivos</translation>
 <translation id="5774515636230743468">Manifiesto:</translation>
 <translation id="577624874850706961">Buscar cookies</translation>
 <translation id="5778550464785688721">Control total de dispositivos MIDI</translation>
@@ -3449,7 +3444,6 @@
 <translation id="5900302528761731119">Foto de perfil de Google</translation>
 <translation id="5900623698597156974">Un valor alternativo de TLS 1.0 ha podido establecer un protocolo de enlace con el servidor, pero ya no aceptamos valores de TLS 1.0. Se debe actualizar el servidor para que implemente correctamente la negociación de la versión y admita preferiblemente TLS 1.2.</translation>
 <translation id="590253956165195626">Preguntar si quieres traducir páginas que no estén escritas en un idioma que entiendas.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 elemento}other{# elementos}}</translation>
 <translation id="5904093760909470684">Configuración de proxy</translation>
 <translation id="5906065664303289925">Dirección de hardware:</translation>
 <translation id="5910363049092958439">Guar&amp;dar imagen como...</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb
index f847d22c..be23ffd2 100644
--- a/chrome/app/resources/generated_resources_et.xtb
+++ b/chrome/app/resources/generated_resources_et.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Juurdepääs ükskõik millisele nimetatud USB-seadmele</translation>
 <translation id="1038168778161626396">Ainult šifreerimine</translation>
 <translation id="1038842779957582377">tundmatu nimi</translation>
-<translation id="1040931876666128942">WebUsb-märguanded.</translation>
 <translation id="1042174272890264476">Teie arvutil on ka toote <ph name="SHORT_PRODUCT_NAME" /> sisseehitatud RLZ-teek. RLZ määrab korduva ja isikut mittetuvastava ID-tunnuse, et mõõta konkreetse reklaamikampaania tekitatud otsinguid ja toote <ph name="SHORT_PRODUCT_NAME" /> kasutust. Need sildid kuvatakse vahel ka tootes <ph name="PRODUCT_NAME" /> Google'i otsingupäringutes.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> soovib suure andmekoguse alaliselt teie seadmesse talletada.</translation>
 <translation id="1045157690796831147">Transliteratsioon (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">Uued küpsiste seaded rakenduvad pärast lehe uuesti laadimist.</translation>
 <translation id="14720830734893704">Virtuaalse klaviatuuri toe lubamine.</translation>
 <translation id="1474339897586437869">Faili „<ph name="FILENAME" />” ei laaditud üles. Teie Google Drive’is ei ole piisavalt vaba ruumi.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 parool}other{# parooli}}</translation>
 <translation id="1476949146811612304">Määrake, millist otsingumootorit <ph name="BEGIN_LINK" />omnikastikeses<ph name="END_LINK" /> otsides kasutatakse.</translation>
 <translation id="1477301030751268706">Identiteedi API loa vahemälu</translation>
 <translation id="1478340334823509079">Üksikasjad: <ph name="FILE_NAME" /></translation>
@@ -922,6 +920,7 @@
 <translation id="2326606747676847821">Ava inkognito režiim</translation>
 <translation id="2326931316514688470">&amp;Laadi rakendus uuesti</translation>
 <translation id="2327492829706409234">Luba rakendus</translation>
+<translation id="2329597144923131178">Logige sisse, et tuua kõikidesse seadmetesse järjehoidjad, ajalugu, paroolid ja muud seaded.</translation>
 <translation id="2332131598580221120">Poes kuvamine</translation>
 <translation id="2332742915001411729">Lähtesta vaikeseadetele</translation>
 <translation id="2335122562899522968">See leht lisas küpsisefaile.</translation>
@@ -945,7 +944,6 @@
 <translation id="2359808026110333948">Jätka</translation>
 <translation id="236128817791440714">Soovitatav: seadistage funktsioon Smart Lock Androidile</translation>
 <translation id="236141728043665931">Blokeeri alati juurdepääs mikrofonile</translation>
-<translation id="2365626167708453863">Google Smart Lockist konto valimine</translation>
 <translation id="2367972762794486313">Rakenduste kuvamine</translation>
 <translation id="2368075211218459617">Kontekstipõhise otsingu lubamine.</translation>
 <translation id="2370882663124746154">Luba topelt-pinyini režiim</translation>
@@ -2664,7 +2662,6 @@
 <translation id="4780374166989101364">Lubab katselise laienduse APIs-e. Pange tähele, et laienduste galerii ei luba teil üles laadida laiendusi, mis kasutavad katselist APIs-t.</translation>
 <translation id="4781787911582943401">Suumi ekraanil sisse</translation>
 <translation id="4782449893814226250">Küsisite oma vanemalt, kas võite seda lehte külastada.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPointi esitlus</translation>
 <translation id="4785040501822872973">Arvuti taaskäivitub <ph name="LOGOUT_TIME_LEFT" /> sekundi pärast.
 Uurimise jätkamiseks vajutage mis tahes klahvi.</translation>
@@ -3195,7 +3192,6 @@
 <translation id="5527474464531963247">Samuti võite valida mõne teise ​​võrgu.</translation>
 <translation id="5527963985407842218">Lugejarežiimi käivitamine</translation>
 <translation id="5528368756083817449">Järjehoidjate haldur</translation>
-<translation id="5529098031581368697">Praeguse taustapildi määras „<ph name="APP_NAME" />”</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Üldine</translation>
 <translation id="5533555070048896610">Transliteratsioon (namaste → नमस्ते)</translation>
@@ -3311,7 +3307,6 @@
 <translation id="5702898740348134351">&amp;Muuda otsingumootoreid...</translation>
 <translation id="5703594190584829406">Automaattäite soovitused kuvatakse klaviatuuri kohal, mitte rippmenüüs.</translation>
 <translation id="5704272569086782895">GPU lõimepõhise rasterdamise lubamine.</translation>
-<translation id="570544101664452060">Katselised WebUsb-märguanded.</translation>
 <translation id="5706551819490830015">Halda arveldusaadresse ...</translation>
 <translation id="5707185214361380026">Laienduse laadimine järgmisest asukohast ebaõnnestus:</translation>
 <translation id="5707604204219538797">Järgmine sõna</translation>
@@ -3460,7 +3455,6 @@
 <translation id="5900302528761731119">Google'i profiilifoto</translation>
 <translation id="5900623698597156974">TLS 1.0 taanderežiimi ja serveri vaheline käepigistus õnnestus, kuid TLS 1.0 taanderežiimid ei ole enam toetatud. Serverit tuleb värskendada, et juurutada õigesti versiooniläbirääkimised ja soovitatavalt ka TLS 1.2 tugi.</translation>
 <translation id="590253956165195626">Paku lehtede tõlkimist, mis ei ole teie loetavas keeles.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 üksus}other{# üksust}}</translation>
 <translation id="5904093760909470684">Puhverserveri konfigureerimine</translation>
 <translation id="5906065664303289925">Riistvara aadress:</translation>
 <translation id="5910363049092958439">Sal&amp;vesta pilt nimega...</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb
index d8b0d8e..1344d0f5 100644
--- a/chrome/app/resources/generated_resources_fa.xtb
+++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">‏دسترسی به هر یک از این دستگاه‌های USB</translation>
 <translation id="1038168778161626396">فقط به رمز درآورد</translation>
 <translation id="1038842779957582377">نام ناشناخته</translation>
-<translation id="1040931876666128942">‏اعلان‌های WebUsb.</translation>
 <translation id="1042174272890264476">‏‫همچنین کتابخانه RLZ‏ <ph name="SHORT_PRODUCT_NAME" /> از قبل بر روی رایانه شما نصب شده است. RLZ یک برچسب غیرمنحصر بفرد و غیرقابل‌شناسایی برای سنجش جستجوها و استفاده از <ph name="SHORT_PRODUCT_NAME" /> اختصاص می‌دهد که توسط یک کمپین تبلیغاتی خاص ارائه می‌شود. در بعضی مواقع در <ph name="PRODUCT_NAME" /> این برچسب‌ها در عباراتی که در جستجوی Goole جستجو می‌شوند نمایان می‌شوند.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> می‌خواهد داده‌های بزرگ را برای همیشه در دستگاه شما ذخیره کند.</translation>
 <translation id="1045157690796831147">‏نویسه‌گردانی (namaskar ← ‏നമസ്കാരം)</translation>
@@ -296,7 +295,7 @@
 <translation id="1425734930786274278">کوکی‌های زیر مسدود شدند (کوکی‌های شخص ثالث بدون استثنا مسدود می‌شوند):</translation>
 <translation id="1426410128494586442">بله</translation>
 <translation id="1427049173708736891">‏وقتی تلفن Android شما قفل نباشد و در همین اطراف باشد، قفل <ph name="DEVICE_TYPE" /> خودتان را باز نگه‌دارید— لازم نیست گذرواژه‌تان را تایپ کنید.</translation>
-<translation id="142758023928848008">فعال کردن کلیدهای چسبناک (برای اجرای میانبرهای صفحه‌کلید با تایپ کردن آنها به ترتیب)</translation>
+<translation id="142758023928848008">فعال کردن کلیدهای چسبناک (برای اجرای میان‌برهای صفحه‌کلید با تایپ کردن آنها به ترتیب)</translation>
 <translation id="1429740407920618615">قدرت سیگنال:</translation>
 <translation id="143027896309062157">خواندن و تغییر همه داده‌ها در رایانه‌تان و وب‌سایت‌هایی که بازدید می‌کنید</translation>
 <translation id="1430915738399379752">چاپ</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">تنظیمات جدید کوکی بعد از بارگیری مجدد صفحه اجرا می‌شود.</translation>
 <translation id="14720830734893704">پشتیبانی از صفحه‌کلید مجازی را به کار بیاندازید.</translation>
 <translation id="1474339897586437869">‏«<ph name="FILENAME" />» آپلود نشد. فضای کافی در Google Drive شما وجود ندارد.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{۱ گذرواژه}one{# گذرواژه}other{# گذرواژه}}</translation>
 <translation id="1476949146811612304">‏تنظیم موتور جستجویی که هنگام انجام جستجو از <ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" /> استفاده شود</translation>
 <translation id="1477301030751268706">‏حافظه داخلی کد Identity API</translation>
 <translation id="1478340334823509079">جزئیات: <ph name="FILE_NAME" /></translation>
@@ -682,7 +680,7 @@
 <translation id="1979444449436715782">برگه کیفیت کاهش مقیاس تصویر.</translation>
 <translation id="1979718561647571293">آیا این همان صفحه راه‌اندازی مورد انتظار شماست؟</translation>
 <translation id="1983959805486816857">پس از ایجاد کاربر نظارت‌‌شده جدید، می‌توانید هر زمان که بخواهید از هر دستگاهی، تنظیمات را در <ph name="MANAGEMENT_URL" /> مدیریت کنید.</translation>
-<translation id="1984603991036629094">صفحه کلید آوایی ارمنی</translation>
+<translation id="1984603991036629094">صفحه‌کلید آوایی ارمنی</translation>
 <translation id="1984642098429648350">قراردادن پنجره در راست</translation>
 <translation id="1985136186573666099"><ph name="PRODUCT_NAME" /> از تنظیمات پروکسی سیستم رایانه‌تان برای اتصال به شبکه استفاده می‌کند.</translation>
 <translation id="1986281090560408715">نمایش اخطار را در بالا گوشه سمت چپ صفحه‌ای فعال می‌کند که اطلاعات مربوط به نقاط لمس روی صفحه را نشان می‌دهد.</translation>
@@ -713,7 +711,7 @@
 <translation id="204622017488417136">‏دستگاه شما به نسخه قبلاً نصب شده Chrome باز می‌گردد. همه حساب‌های کاربری و داده‌های محلی حذف می‌شوند. این کار قابل بازگشت نیست.</translation>
 <translation id="2048182445208425546">دسترسی به ترافیک شبکه شما</translation>
 <translation id="2049137146490122801">دسترسی به فایل‌های محلی بر روی دستگاه از طریق سرپرست غیرفعال شده است.</translation>
-<translation id="204914487372604757">ایجاد میانبر</translation>
+<translation id="204914487372604757">ایجاد میان‌بر</translation>
 <translation id="2049639323467105390">این دستگاه توسط <ph name="DOMAIN" /> مدیریت می‌شود.</translation>
 <translation id="2050339315714019657">عمودی</translation>
 <translation id="2052610617971448509">‏شما به حد کافی sandbox ندارید!</translation>
@@ -920,6 +918,7 @@
 <translation id="2326606747676847821">ناشناس شوید</translation>
 <translation id="2326931316514688470">&amp;تازه‌سازی برنامه</translation>
 <translation id="2327492829706409234">فعال کردن برنامه</translation>
+<translation id="2329597144923131178">برای دریافت نشانک‌ها، سابقه، گذرواژه‌ها و سایر تنظیماتتان در همه دستگاه‌ها، وارد سیستم شوید.</translation>
 <translation id="2332131598580221120">مشاهده در فروشگاه</translation>
 <translation id="2332742915001411729">بازنشانی روی موارد پیش‌فرض</translation>
 <translation id="2335122562899522968">این صفحه کوکی‌ها را تنظیم می‌کند.</translation>
@@ -943,7 +942,6 @@
 <translation id="2359808026110333948">ادامه</translation>
 <translation id="236128817791440714">‏توصیه می‌شود: راه‌اندازی Smart Lock برای Android</translation>
 <translation id="236141728043665931">دسترسی به میکروفون همیشه مسدود شود</translation>
-<translation id="2365626167708453863">‏حسابی را از Google Smart Lock انتخاب کنید</translation>
 <translation id="2367972762794486313">نمایش برنامه‌ها</translation>
 <translation id="2368075211218459617">جستجوی متنی را فعال کنید.</translation>
 <translation id="2370882663124746154">‏فعال کردن حالت Double-Pinyin</translation>
@@ -1016,7 +1014,7 @@
 <translation id="2471964272749426546">‏روش ورودی تامیل (Tamil99)</translation>
 <translation id="2473195200299095979">ترجمه این صفحه</translation>
 <translation id="2475982808118771221">یک خطا روی داد</translation>
-<translation id="247772113373397749">صفحه کلید چندزبانه کانادایی</translation>
+<translation id="247772113373397749">صفحه‌کلید چندزبانه کانادایی</translation>
 <translation id="2478176599153288112">مجوزهای فایل رسانه‌ای برای «<ph name="EXTENSION" />»</translation>
 <translation id="2478830106132467213">قفل این <ph name="DEVICE_TYPE" /> فقط زمانی باز می‌شود که تلفنتان در فاصله یک دست با شما قرار داشته باشد.</translation>
 <translation id="2479780645312551899">این بار همه افزایه‌ها اجرا شوند</translation>
@@ -1042,7 +1040,7 @@
 <translation id="2498857833812906273">‏هنگام خروج از Chrome درصورتی‌که برنامه‌های میزبانی شده در حال اجرا هستند، اعلانی نمایش داده شود.</translation>
 <translation id="2501173422421700905">گواهی در انتظار</translation>
 <translation id="2501278716633472235">بازگشت</translation>
-<translation id="2501797496290880632">تایپ کردن میانبر</translation>
+<translation id="2501797496290880632">تایپ کردن میان‌بر</translation>
 <translation id="2502441965851148920">به‌روزرسانی‌های خودکار فعال شده‌اند. سرپرست سیستم شما به‌روزرسانی‌های دستی را غیرفعال کرده است.</translation>
 <translation id="2504775205691825589">سروری که این صفحه وب را میزبانی می‌کند ممکن است بیش از حد بار داشته باشد یا تحت سرویس و نگهداری باشد.
         برای جلوگیری از ایجاد ترافیک بیش از حد و بدتر کردن وضعیت،
@@ -1119,7 +1117,7 @@
 <translation id="2607991137469694339">روش‌ ورودی تامیل (آوایی)</translation>
 <translation id="2608770217409477136">استفاده از تنظیمات پیش‌فرض</translation>
 <translation id="2609371827041010694">همیشه در این سایت اجرا شود</translation>
-<translation id="2609896558069604090">ایجاد میانبرها...</translation>
+<translation id="2609896558069604090">ایجاد میان‌برها...</translation>
 <translation id="2610260699262139870">اندازه &amp;واقعی</translation>
 <translation id="2610780100389066815">‏امضای لیست اطمینان Microsoft</translation>
 <translation id="2612676031748830579">شماره کارت</translation>
@@ -1453,7 +1451,7 @@
 <translation id="3056670889236890135">فقط می‌توانید تنظیمات کاربر کنونی را ویرایش کنید. به این کاربر بروید تا تنظیمات آن را ویرایش کنید.</translation>
 <translation id="3057592184182562878">‏نمایش دستگاه‌های MTP به صورت یک ذخیره‌سازی فایل در مدیریت فایل.</translation>
 <translation id="3057861065630527966">از عکس‌ها و ویدیوهایتان پشتیبان بگیرید</translation>
-<translation id="305803244554250778">ایجاد میانبرهای برنامه در قسمت‌های زیر:</translation>
+<translation id="305803244554250778">ایجاد میان‌برهای برنامه در قسمت‌های زیر:</translation>
 <translation id="3058212636943679650">‏درصورتی‌که لازم شود سیستم عامل رایانهٔ خود را بازیابی کنید، به یک کارت SD بازیابی یا کارت حافظهٔ USB نیاز خواهید داشت.</translation>
 <translation id="305932878998873762">‏حافظه داخلی ساده HTTP حافظه داخلی جدیدی است. این قابلیت برای تخصیص فضای دیسک به سیستم پرونده‌ای تکیه می‌کند.</translation>
 <translation id="3060433672989552055">با توجه به رفتار بازگشت پیش‌فرض، این سایت مسدود شد.</translation>
@@ -2008,7 +2006,7 @@
 <translation id="3778740492972734840">ابزارهای &amp;برنامه نویس</translation>
 <translation id="378312418865624974">خواندن شناسه بی‌نظیر در این رایانه</translation>
 <translation id="3783640748446814672">دگرساز</translation>
-<translation id="3785308913036335955">نمایش میانبر «برنامه‌ها»</translation>
+<translation id="3785308913036335955">نمایش میان‌بر «برنامه‌ها»</translation>
 <translation id="3785852283863272759">ایمیل کردن مکان صفحه</translation>
 <translation id="3786301125658655746">شما آفلاین هستید</translation>
 <translation id="3788090790273268753">‏گواهی این سایت در سال ۲۰۱۶ منقضی می‌شود و زنجیره گواهی حاوی یک گواهی با امضای SHA-1 است.</translation>
@@ -2042,7 +2040,7 @@
 <translation id="3819800052061700452">&amp;تمام صفحه</translation>
 <translation id="3822265067668554284">به هیچ سایتی اجازه داده نشود مکان فیزیکی شما را ردیابی کند</translation>
 <translation id="382518646247711829">اگر از سرور پراکسی استفاده می‌کنید...</translation>
-<translation id="3825863595139017598">صفحه کلید مغولی</translation>
+<translation id="3825863595139017598">صفحه‌کلید مغولی</translation>
 <translation id="3827306204503227641">افزایه‌های آزمایشی نشده همچنان مجاز باشند</translation>
 <translation id="38275787300541712">‏پس از انجام کار، Enter را فشار دهید</translation>
 <translation id="3827774300009121996">&amp;تمام صفحه</translation>
@@ -2073,7 +2071,7 @@
 <translation id="3858678421048828670">صفحه‌کلید ایتالیایی</translation>
 <translation id="3859360505208332355">همیشه به این افزایه‌ها در <ph name="HOST" /> اجازه داده شود</translation>
 <translation id="3866249974567520381">توضیح</translation>
-<translation id="3866443872548686097">رسانه بازیابی شما آماده است. می‌توانید آن را از سیستم خود بردارید.</translation>
+<translation id="3866443872548686097">رسانه بازیابی شما آماده است. می‌توانید آن را از سیستم خود جدا کنید.</translation>
 <translation id="3867944738977021751">فیلدهای گواهی</translation>
 <translation id="3868718841498638222">شما به کانال <ph name="CHANNEL_NAME" /> تغییر وضعیت داده‌اید.</translation>
 <translation id="3869917919960562512">فهرست اشتباه.</translation>
@@ -2629,7 +2627,7 @@
 <translation id="4746971725921104503">به نظر می‌رسد که شما از قبل در حال مدیریت کاربری با همان نام هستید. آیا مایلید <ph name="LINK_START" /><ph name="USER_DISPLAY_NAME" /> را به این دستگاه وارد کنید<ph name="LINK_END" />؟</translation>
 <translation id="4747271164117300400">مقدونی</translation>
 <translation id="4747597332667805440">رابط کاربری حباب بازیابی جلسه را فعال کنید.</translation>
-<translation id="4749157430980974800">صفحه کلید گرجی</translation>
+<translation id="4749157430980974800">صفحه‌کلید گرجی</translation>
 <translation id="4750394297954878236">پیشنهادات</translation>
 <translation id="475088594373173692">کاربر اول</translation>
 <translation id="4753602155423695878">‏پویانمایی نوار پیشرفت بارگیری صفحه تلفن Android</translation>
@@ -2650,7 +2648,6 @@
 <translation id="4780374166989101364">‏APIهای برنامه آزمایشی را فعال می‌کند. توجه داشته باشید که گالری برنامهٔ افزودنی به شما برای آپلود افزونه‌هایی که از APIهای آزمایشی استفاده می‌کنند، اجازه نمی‌دهد.</translation>
 <translation id="4781787911582943401">بزرگ‌نمایی صفحه</translation>
 <translation id="4782449893814226250">از والدینتان پرسیدید آیا اجازه بازدید از این صفحه را دارید.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{۱ کیلوبایت}one{# کیلوبایت}other{# کیلوبایت}}</translation>
 <translation id="4784330909746505604">‏ارائه PowerPoint </translation>
 <translation id="4785040501822872973">این رایانه بعد از <ph name="LOGOUT_TIME_LEFT" /> ثانیه  بازنشانی می‌شود. هر دکمه‌ای را که می‌خواهید فشار دهید تا کاوش ادامه پیدا کند.</translation>
 <translation id="4786993863723020412">خطا در خواندن حافظهٔ پنهان</translation>
@@ -2745,7 +2742,7 @@
 <translation id="49088176676474409">‏پنهان کردن مقادیر VPD.</translation>
 <translation id="4910021444507283344">WebGL</translation>
 <translation id="4910673011243110136">شبکه‌های خصوصی</translation>
-<translation id="4911714727432509308">میانبرهای صفحه‌کلید به هیچ برنامهٔ افزودنی اختصاص داده نشده است.</translation>
+<translation id="4911714727432509308">میان‌برهای صفحه‌کلید به هیچ برنامهٔ افزودنی اختصاص داده نشده است.</translation>
 <translation id="4912643508233590958">تعداد خروج از حالت بی‌حرکت</translation>
 <translation id="4916679969857390442">لنز</translation>
 <translation id="4918021164741308375"><ph name="ORIGIN" /> می‌خواهد با افزونه «<ph name="EXTENSION_NAME" />» ارتباط برقرار کند</translation>
@@ -3052,7 +3049,7 @@
 <translation id="5355097969896547230">یافتن دوباره</translation>
 <translation id="5355351445385646029">برای انتخاب کاندید، فاصله را فشار دهید</translation>
 <translation id="5355926466126177564">‏افزونه «<ph name="EXTENSION_NAME" />»، صفحه‌ای را تغییر داده است که هنگام جستجو از Omnibox نشان داده می‌شود.</translation>
-<translation id="5357579842739549440">میانبرهای صفحه کلید برای اشکال‌زدایی</translation>
+<translation id="5357579842739549440">میان‌برهای صفحه‌کلید برای اشکال‌زدایی</translation>
 <translation id="5359419173856026110">هنگامی که افزایش سرعت سخت‌افزار فعال است، سرعت فریم واقعی یک صفحه را در هر ثانیه برای فریم ها نمایش می‌دهد.</translation>
 <translation id="5360150013186312835">نمایش در نوار ابزار</translation>
 <translation id="5362741141255528695">فایل کلید خصوصی را انتخاب کنید.</translation>
@@ -3070,7 +3067,7 @@
 <translation id="537813040452600081">صفحاتی که در این پنجره مشاهده می‌کنید در سابقه مروگر نشان داده نمی‌شوند و بعد از خروج از سیستم هیچ رد دیگری در رایانه از خود به جای نمی‌گذارند (مانند کوکی‌ها). فایل‌هایی که دانلود می‌کنید و نشانک‌هایی که ایجاد می‌کنید حفظ نمی‌شوند.</translation>
 <translation id="5379140238605961210">ادامه مسدود کردن دسترسی به میکروفون</translation>
 <translation id="5379268888377976432">واگرد حذف</translation>
-<translation id="5380103295189760361">‏برای مشاهده میانبرهای صفحه‌ کلید مربوط به این اصلاح‌کننده‌ها کلیدهای Shift ،Alt ،Control یا Search را نگه دارید.</translation>
+<translation id="5380103295189760361">‏برای مشاهده میان‌برهای صفحه‌ کلید مربوط به این اصلاح‌کننده‌ها کلیدهای Shift ،Alt ،Control یا Search را نگه دارید.</translation>
 <translation id="5382392428640372740">فعال کردن ردیابی پیمایش</translation>
 <translation id="5388588172257446328">نام کاربری:</translation>
 <translation id="5390284375844109566">پایگاه داده فهرست‌بندی شده</translation>
@@ -3115,7 +3112,7 @@
 <translation id="5436510242972373446">جستجوی <ph name="SITE_NAME" />:</translation>
 <translation id="5438430601586617544">(غیر فشرده)</translation>
 <translation id="54401264925851789">اطلاعات امنیتی صفحه</translation>
-<translation id="544083962418256601">ایجاد میانبرها...</translation>
+<translation id="544083962418256601">ایجاد میان‌برها...</translation>
 <translation id="5441100684135434593">شبکه کابلی</translation>
 <translation id="5448293924669608770">اوه، هنگام ورود به سیستم خطایی رخ داد</translation>
 <translation id="5449588825071916739">نشانک‌گذاری همه برگه‌ها...</translation>
@@ -3181,7 +3178,6 @@
 <translation id="5527474464531963247">همچنین می‌توانید شبکه دیگری را انتخاب کنید.</translation>
 <translation id="5527963985407842218">فعال‌سازی حالت خواننده</translation>
 <translation id="5528368756083817449">مدیر نشانک</translation>
-<translation id="5529098031581368697">کاغذدیواری فعلی توسط «<ph name="APP_NAME" />» تنظیم شده است</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">سراسری</translation>
 <translation id="5533555070048896610">‏نویسه‌گردانی (namaste ← ‏नमस्ते)</translation>
@@ -3297,7 +3293,6 @@
 <translation id="5702898740348134351">&amp;ویرایش موتورهای جستجو...</translation>
 <translation id="5703594190584829406">پیشنهادهای تکمیل خودکار را در بالای صفحه‌کلید، به جای حالت کشویی نشان می‌دهد.</translation>
 <translation id="5704272569086782895">‏فعال کردن شطرنجی‌سازی GPU رشته‌ای.</translation>
-<translation id="570544101664452060">‏اعلان‌های آزمایشی WebUsb.</translation>
 <translation id="5706551819490830015">مدیریت آدرس‌های صورت‌حساب...</translation>
 <translation id="5707185214361380026">بارگیری برنامه افزودنی از اینجا ناموفق بود:</translation>
 <translation id="5707604204219538797">کلمه بعدی</translation>
@@ -3446,7 +3441,6 @@
 <translation id="5900302528761731119">‏عکس نمایهٔ Google</translation>
 <translation id="5900623698597156974">‏جایگزین TLS 1.0 توانست با سرور ارتباط برقرار کند اما ما دیگر جایگزین‌های TLS 1.0 را نمی‌پذیریم. سرور باید ارتقا یابد تا به‌طور صحیح ارزیابی نسخه را انجام دهد و ترجیحاً از TLS 1.2 پشتیبانی کند.</translation>
 <translation id="590253956165195626">پیشنهاد ترجمه برای صفحات (صفحاتی که به زبانی است که نمی‌دانم).</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{۱ مورد}one{# مورد}other{# مورد}}</translation>
 <translation id="5904093760909470684">پیکربندی پراکسی</translation>
 <translation id="5906065664303289925">آدرس سخت‌افزار:</translation>
 <translation id="5910363049092958439">ذ&amp;خیره فایل تصویری به‌عنوان...</translation>
@@ -3921,7 +3915,7 @@
 <translation id="6626108645084335023">‏در انتظار بررسی DNS.</translation>
 <translation id="6628328486509726751">زمان آپلود <ph name="WEBRTC_LOG_UPLOAD_TIME" /></translation>
 <translation id="6629841649550503054">‏همه در <ph name="BEGIN_LINK" />Google Drive<ph name="END_LINK" /> پشتیبان گرفته شدند</translation>
-<translation id="6630452975878488444">میانبر انتخاب</translation>
+<translation id="6630452975878488444">میان‌بر انتخاب</translation>
 <translation id="6630752851777525409"><ph name="EXTENSION_NAME" /> خواستار دسترسی دائم به یک گواهی است تا خودش را از طرف شما احراز هویت کند.</translation>
 <translation id="6631802470730636970">فعال کردن افزودن به قفسه</translation>
 <translation id="6634865548447745291">در حال حاضر نمی‌توانید از <ph name="SITE" /> بازدید کنید زیرا <ph name="BEGIN_LINK" />این گواهینامه باطل شده است<ph name="END_LINK" />. معمولاً خطاهای شبکه و حمله‌ها موقتی هستند، بنابراین احتمالاً این صفحه بعداً کار خواهد کرد.</translation>
@@ -4427,7 +4421,7 @@
 <translation id="7396845648024431313"><ph name="APP_NAME" /> در هنگام راه‌اندازی سیستم شروع به کار می‌کند و در پس‌زمینه همچنان فعال خواهد بود، حتی زمانی که تمام پنجره‌های دیگر <ph name="PRODUCT_NAME" /> را ببندید.</translation>
 <translation id="7400418766976504921">نشانی وب</translation>
 <translation id="740083207982962331">‏لطفاً صبر کنید تا Chromebox شما مجدداً راه‌اندازی شود...</translation>
-<translation id="7401543881546089382">حذف میانبر</translation>
+<translation id="7401543881546089382">حذف میان‌بر</translation>
 <translation id="7401762151840183030">تنظیمات شما به پیش‌فرض‌های اولیه آنها بازیابی می‌شوند. با این کار صفحه اصلی، صفحه «برگه جدید» و موتور جستجویتان بازنشانی می‌شود، افزونه‌هایتان غیرفعال می‌شوند و پین همه برگه‌ها برداشته می‌شود. سایر داده‌های موقت و داده‌های حافظه پنهان هم (مانند کوکی‌ها، داده‌های سایت و محتوا) پاک می‌شوند.</translation>
 <translation id="7405422715075171617">اسکن شماره کارت اعتباری جدید را هنگام پر کردن فرم کارت اعتباری فعال کنید.</translation>
 <translation id="740624631517654988">پنجره‌های بازشو مسدود شدند</translation>
@@ -4730,7 +4724,7 @@
 <translation id="7839804798877833423">دریافت این فایل‌ها تقریباً <ph name="FILE_SIZE" /> از داده تلفن همراه شما را مصرف می‌کند.</translation>
 <translation id="7839809549045544450">‏این سرور دارای یک کلید عمومی Diffie-Hellman یک بار مصرف است</translation>
 <translation id="7839963980801867006">‏انتخاب کنید کدام IME برنامه افزودنی در منوی زبان فعال شود.</translation>
-<translation id="7842062217214609161">بدون میانبر</translation>
+<translation id="7842062217214609161">بدون میان‌بر</translation>
 <translation id="7842346819602959665">جدیدترین نسخه برنامهٔ افزودنی "<ph name="EXTENSION_NAME" />" به مجوزهای بیشتری نیاز دارد، بنابراین غیر فعال شده است.</translation>
 <translation id="7844992432319478437">به‌روزرسانی تفاوت</translation>
 <translation id="7845849068167576533">‏حتی اگر در گذشته از این وب‌سایت بازدید کرده‌اید، اکنون امن نیست. Google Safe Browsing به تازگی در <ph name="SITE" />، ‏<ph name="BEGIN_LINK" />بدافزار شناسایی کرده است<ph name="END_LINK" />. گاهی اوقات وب‌سایت‌هایی که معمولاً امن هستند، با بدافزار آلوده می‌شوند. منبع محتوای مخرب <ph name="SUBRESOURCE_HOST" /> است که یک توزیع‌کننده بدافزار شناخته شده می‌باشد.</translation>
@@ -4809,7 +4803,7 @@
 <translation id="7947962633355574091">کپی آدرس ویدیو</translation>
 <translation id="795025003224538582">راه‌اندازی مجدد نشود</translation>
 <translation id="7953739707111622108">این دستگاه باز نمی‌شود زیرا سیستم فایل‌ آن شناسایی نشد.</translation>
-<translation id="7953955868932471628">مدیریت میانبرها</translation>
+<translation id="7953955868932471628">مدیریت میان‌برها</translation>
 <translation id="7955383984025963790">برگه ۵</translation>
 <translation id="7957054228628133943">مدیریت انسداد پنجره بازشو</translation>
 <translation id="7959074893852789871">این فایل دارای چندین مجوز است، برخی از آن‌ها وارد نشده‌اند:</translation>
@@ -4845,7 +4839,7 @@
 <translation id="7988930390477596403">‏دفعه بعد که قفل <ph name="DEVICE_TYPE" /> را باز کنید، فعال می‌شود. با Smart Lock، تلفنتان قفل این دستگاه را، بدون گذرواژه، باز می‌کند. برای فعال کردن Smart Lock، بلوتوث روشن می‌شود.</translation>
 <translation id="7989023212944932320">‏Google Safe Browsing به تازگی در <ph name="SITE" />، ‏<ph name="BEGIN_LINK" />بدافزار شناسایی کرده است<ph name="END_LINK" />. گاهی اوقات وب‌سایت‌هایی که معمولاً امن هستند، با بدافزار آلوده می‌شوند. منبع محتوای مخرب <ph name="SUBRESOURCE_HOST" /> است که یک توزیع‌کننده بدافزار شناخته شده می‌باشد. باید بعد از گذشت چند ساعت به سایت برگردید.</translation>
 <translation id="7994370417837006925">ورود چندگانه به سیستم</translation>
-<translation id="799547531016638432">حذف میانبر</translation>
+<translation id="799547531016638432">حذف میان‌بر</translation>
 <translation id="7996005831155352675">فعال کردن تکمیل خودکار با یک کلیک</translation>
 <translation id="79962507603257656">وضعیت دانلود در مرکز اعلان</translation>
 <translation id="7997089631332811254">‏(|شروع به کار مجدد| Chrome لازم است)</translation>
@@ -5435,7 +5429,7 @@
 <translation id="8848709220963126773">‏تغییر حالت کلید shift</translation>
 <translation id="8852366862412129888">‏سایت دارای منابع HTTP است.</translation>
 <translation id="8852742364582744935">برنامه‌ها و افزودنه‌های زیر اضافه شدند:</translation>
-<translation id="885381502874625531">صفحه کلید بلاروسی</translation>
+<translation id="885381502874625531">صفحه‌کلید بلاروسی</translation>
 <translation id="8856844195561710094">توقف کاوش دستگاه بلوتوث ناموفق بود.</translation>
 <translation id="885701979325669005">فضای ذخیره‌سازی</translation>
 <translation id="8859057652521303089">انتخاب زبان:</translation>
@@ -5468,7 +5462,7 @@
 <translation id="8899388739470541164">ویتنامی</translation>
 <translation id="8899851313684471736">باز کردن پیوند در &amp;پنجره جدید</translation>
 <translation id="8900820606136623064">مجارستانی</translation>
-<translation id="8901822611024316615">‏صفحه کلید QWERTY چک</translation>
+<translation id="8901822611024316615">‏صفحه‌کلید QWERTY چک</translation>
 <translation id="890308499387283275">‏Chrome نمی‌تواند این فایل را دانلود کند.</translation>
 <translation id="8903921497873541725">بزرگ‌نمایی</translation>
 <translation id="8908902564709148335">هشدار: پرچم --اسکریپت-نیاز-به-اقدام-دارد را در این رایانه فعال کرده‌اید که قابلیت‌های این برنامه افزودنی را محدود می‌کند. با وجود این، شاید سایر دستگاه‌ها از این پرچم پشتیبانی نکنند یا آن را فعال کرده باشند. در این دستگاه‌ها، این برنامه افزودنی می‌تواند این موارد را نیز انجام دهد:</translation>
@@ -5663,7 +5657,7 @@
 <translation id="9159562891634783594">‏گزینه ثبت چاپگرهای cloud ثبت نشده را در بخش پیش‌نمایش چاپ فعال می‌کند.</translation>
 <translation id="9166510596677678112">ارسال ایمیل برای این شخص</translation>
 <translation id="916745092148443205">هایلایت شدن در اثر ضربه</translation>
-<translation id="9169496697824289689">مشاهده میانبرهای صفحه کلید</translation>
+<translation id="9169496697824289689">مشاهده میان‌برهای صفحه‌کلید</translation>
 <translation id="9169664750068251925">همیشه مسدود در این سایت</translation>
 <translation id="9170848237812810038">&amp;واگرد</translation>
 <translation id="9170884462774788842">‏برنامه‌ای دیگر بر روی رایانه شما یک طرح زمینه را اضافه کرده است که ممکن است نحوه کارکرد Chrome را تغییر دهد.</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb
index ec553ed..8b3f861 100644
--- a/chrome/app/resources/generated_resources_fi.xtb
+++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Käyttää kaikkia näitä USB-laitteita</translation>
 <translation id="1038168778161626396">Vain salakoodaus</translation>
 <translation id="1038842779957582377">tuntematon nimi</translation>
-<translation id="1040931876666128942">WebUsb-ilmoitukset</translation>
 <translation id="1042174272890264476"><ph name="SHORT_PRODUCT_NAME" /> sisältää sisäänrakennetun RLZ-kirjaston. RLZ tuottaa ei-yksilöivän tagin, jolla voidaan mitata tietyn kampanjan aiheuttamia hakuja ja tuotteen <ph name="SHORT_PRODUCT_NAME" /> käyttöä. <ph name="PRODUCT_NAME" /> näyttää ajoittain näitä tunnisteita Google-hakujen kyselyissä.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> haluaa tallentaa suuria tietomääriä pysyvästi laitteellesi.</translation>
 <translation id="1045157690796831147">Translitterointi (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Uudet evästeasetukset tulevat voimaan päivitettyäsi sivun.</translation>
 <translation id="14720830734893704">Ota virtuaalinäppäimistön tuki käyttöön.</translation>
 <translation id="1474339897586437869">Tiedostoa <ph name="FILENAME" /> ei lähetetty. Google Drivessasi ei ole riittävästi vapaata tallennustilaa.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 salasana}other{# salasanaa}}</translation>
 <translation id="1476949146811612304">Valitse <ph name="BEGIN_LINK" />omniboxissa<ph name="END_LINK" /> käytettävä hakukone.</translation>
 <translation id="1477301030751268706">Henkilöllisyyssovellusliittymän tunnuksen välimuisti</translation>
 <translation id="1478340334823509079">Lisätiedot: <ph name="FILE_NAME" /></translation>
@@ -919,6 +917,7 @@
 <translation id="2326606747676847821">Siirry incognito-tilaan</translation>
 <translation id="2326931316514688470">&amp;Lataa sovellus uudelleen</translation>
 <translation id="2327492829706409234">Ota sovellus käyttöön</translation>
+<translation id="2329597144923131178">Kirjaudu ja käytä kirjanm., historiaa, salasan. ja muita asetuksia kaikissa laitteissasi.</translation>
 <translation id="2332131598580221120">Näytä Web Storessa</translation>
 <translation id="2332742915001411729">Palauta oletusarvo</translation>
 <translation id="2335122562899522968">Tämä sivu asettaa evästeitä.</translation>
@@ -942,7 +941,6 @@
 <translation id="2359808026110333948">Jatka</translation>
 <translation id="236128817791440714">Suositus: ota käyttöön Androidin Smart Lock</translation>
 <translation id="236141728043665931">Estä aina mikrofonin käyttö</translation>
-<translation id="2365626167708453863">Valitse tili Google Smart Lockista</translation>
 <translation id="2367972762794486313">Näytä sovellukset</translation>
 <translation id="2368075211218459617">Ota kontekstihaku käyttöön.</translation>
 <translation id="2370882663124746154">Ota Double-Pinyin-tila käyttöön</translation>
@@ -2642,7 +2640,6 @@
 <translation id="4780374166989101364">Ottaa kokeelliset laajennussovellusliittymät käyttöön. Huomaa, että laajennusgalleria ei anna lähettää laajennuksia, jotka käyttävät kokeellisia sovellusliittymiä.</translation>
 <translation id="4781787911582943401">Zoomaa lähemmäs</translation>
 <translation id="4782449893814226250">Pyysit vanhemmiltasi lupaa käydä tällä sivulla.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 Kt}other{# Kt}}</translation>
 <translation id="4784330909746505604">PowerPoint-esitys</translation>
 <translation id="4785040501822872973">Tämä tietokone nollataan <ph name="LOGOUT_TIME_LEFT" /> sekunnin kuluttua. Paina mitä tahansa näppäintä jatkaaksesi käyttöä.</translation>
 <translation id="4786993863723020412">Välimuistin lukuvirhe</translation>
@@ -3170,7 +3167,6 @@
 <translation id="5527474464531963247">Voit myös valita muun verkon.</translation>
 <translation id="5527963985407842218">Lukutilan painikkeen näyttäminen</translation>
 <translation id="5528368756083817449">Kirjanmerkkien hallinta</translation>
-<translation id="5529098031581368697"><ph name="APP_NAME" /> asensi nykyisen taustakuvan</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Maailmanlaajuinen</translation>
 <translation id="5533555070048896610">Translitterointi (namaste → नमस्ते)</translation>
@@ -3286,7 +3282,6 @@
 <translation id="5702898740348134351">Muokkaa hakukon&amp;eita...</translation>
 <translation id="5703594190584829406">Näyttää automaattisen täytön ehdotukset näppäimistön yläosassa, ei avattavassa valikossa.</translation>
 <translation id="5704272569086782895">Ota käyttöön monisäikeinen grafiikkasuorittimella rasterointi.</translation>
-<translation id="570544101664452060">Kokeelliset WebUsb-ilmoitukset</translation>
 <translation id="5706551819490830015">Hallinnoi laskutusosoitteita…</translation>
 <translation id="5707185214361380026">Laajennuksen lataaminen seuraavasta kohteesta epäonnistui:</translation>
 <translation id="5707604204219538797">Seuraava sana</translation>
@@ -3433,7 +3428,6 @@
 <translation id="5900302528761731119">Google-profiilin valokuva</translation>
 <translation id="5900623698597156974">TLS 1.0 -varatoiminto onnistui kättelemään palvelimen kanssa, mutta emme enää hyväksy TLS 1.0 -varatoimintoja. Palvelin täytyy päivittää, jotta versiontarkistus ja mahdollisesti myös suositeltava TLS 1.2 -tuki voidaan ottaa käyttöön.</translation>
 <translation id="590253956165195626">Tarjoa käännöstä muunkielisille sivuille.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 kohde}other{# kohdetta}}</translation>
 <translation id="5904093760909470684">Välityspalvelimen määritykset</translation>
 <translation id="5906065664303289925">Laitteiston osoite:</translation>
 <translation id="5910363049092958439">T&amp;allenna kuva nimellä...</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb
index 6d136b5..5d33f4b 100644
--- a/chrome/app/resources/generated_resources_fil.xtb
+++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">I-access ang anuman sa mga USB device na ito</translation>
 <translation id="1038168778161626396">Encipher Lamang</translation>
 <translation id="1038842779957582377">Hindi kilalang pangalan</translation>
-<translation id="1040931876666128942">Mga notification ng WebUsb.</translation>
 <translation id="1042174272890264476">Ang iyong computer ay may naka-built in din na RLZ library ng <ph name="SHORT_PRODUCT_NAME" />. Nagtatalaga ang RLZ ng hindi natatangi at hindi personal na nakakapagpakilalang tag upang sukatin ang mga paghahanap at paggamit ng <ph name="SHORT_PRODUCT_NAME" /> na nahimok ng isang partikular na kampanya sa pag-promote. Lumalabas minsan ang mga label na ito sa mga query sa Paghahanap sa Google sa <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285">Gustong ng <ph name="URL" /> na permanenteng mag-imbak ng malaking data sa iyong device.</translation>
 <translation id="1045157690796831147">Transliteration (namaskar → നമസ്കാരം)</translation>
@@ -330,7 +329,6 @@
 <translation id="1470719357688513792">Magkakabisa ang mga bagong setting ng cookie pagkatapos i-reload ang pahina.</translation>
 <translation id="14720830734893704">I-enable ang suporta sa virtual keyboard.</translation>
 <translation id="1474339897586437869">Hindi na-upload ang "<ph name="FILENAME" />." Walang sapat na bakanteng espasyo sa iyong Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 password}one{# password}other{# na password}}</translation>
 <translation id="1476949146811612304">Itakda kung aling search engine ang gagamitin kapag naghahanap mula sa <ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Identity API Token Cache</translation>
 <translation id="1478340334823509079">Mga detalye: <ph name="FILE_NAME" /></translation>
@@ -926,6 +924,7 @@
 <translation id="2326606747676847821">Maging Incognito</translation>
 <translation id="2326931316514688470">I-&amp;reload ang app</translation>
 <translation id="2327492829706409234">Paganahin ang app</translation>
+<translation id="2329597144923131178">Mag-sign in upang makuha ang iyong mga bookmark, history, password at ibang mga setting sa lahat ng iyong device.</translation>
 <translation id="2332131598580221120">Tingnan sa store</translation>
 <translation id="2332742915001411729">I-reset sa default</translation>
 <translation id="2335122562899522968">Nagtatakda ang pahinang ito ng cookies.</translation>
@@ -949,7 +948,6 @@
 <translation id="2359808026110333948">Magpatuloy</translation>
 <translation id="236128817791440714">Inirerekomenda: I-set up ang Smart Lock para sa Android</translation>
 <translation id="236141728043665931">Palaging i-block ang pag-access sa mikropono</translation>
-<translation id="2365626167708453863">Pumili ng account mula sa iyong Google Smart Lock</translation>
 <translation id="2367972762794486313">Ipakita ang apps</translation>
 <translation id="2368075211218459617">I-enable ang Paghahanap ayon sa Konteksto.</translation>
 <translation id="2370882663124746154">Paganahin ang Double-Pinyin mode</translation>
@@ -2668,7 +2666,6 @@
 <translation id="4780374166989101364">Pinapagana ang mga API ng extension na pang-eksperimento. Tandaan na hindi ka pinapayagan ng gallery ng extension upang mag-upload ng mga extension na gumagamit ng mga API na pang-eksperimento.</translation>
 <translation id="4781787911582943401">Mag-zoom in sa screen</translation>
 <translation id="4782449893814226250">Tinanong mo sa iyong mga magulang kung maaari mong bisitahin ang page na ito.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kilobyte}one{# kilobyte}other{# na kilobyte}}</translation>
 <translation id="4784330909746505604">Presentation ng PowerPoint</translation>
 <translation id="4785040501822872973">Ang computer na ito ay magre-reset sa loob ng <ph name="LOGOUT_TIME_LEFT" /> (na) mga segundo.
 Pumindot ng anumang key upang magpatuloy sa pagtuklas.</translation>
@@ -3199,7 +3196,6 @@
 <translation id="5527474464531963247">Maaari ka ring pumili ng isa pang network.</translation>
 <translation id="5527963985407842218">Pagti-trigger sa Reader Mode</translation>
 <translation id="5528368756083817449">Manager ng bookmark </translation>
-<translation id="5529098031581368697">Ang kasalukuyang wallpaper ay itinakda ng '<ph name="APP_NAME" />'</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Pandaigdigan</translation>
 <translation id="5533555070048896610">Transliteration (namaste → नमस्ते)</translation>
@@ -3315,7 +3311,6 @@
 <translation id="5702898740348134351">I-&amp;edit ang Mga Search Engine...</translation>
 <translation id="5703594190584829406">Ipinapakita ang mga suhestyon ng Autofill sa itaas ng keyboard sa halip ng isang dropdown.</translation>
 <translation id="5704272569086782895">I-enable ang threaded GPU rasterization.</translation>
-<translation id="570544101664452060">Mga pang-eksperimentong notification ng WebUsb.</translation>
 <translation id="5706551819490830015">Pamahalaan ang mga billing address...</translation>
 <translation id="5707185214361380026">Hindi na-load ang extension mula sa:</translation>
 <translation id="5707604204219538797">Susunod na salita</translation>
@@ -3464,7 +3459,6 @@
 <translation id="5900302528761731119">Larawan sa Profile sa Google</translation>
 <translation id="5900623698597156974">Nagawa ng isang TLS 1.0 fallback na mag-handshake sa server, ngunit hindi na kami tumatanggap ng mga TLS 1.0 fallback. Dapat ma-update ang server upang wastong maipatupad ang negosasyon ng bersyon at mas mabuti kung sinusuportahan ang TLS 1.2.</translation>
 <translation id="590253956165195626">Mag-alok na isalin ang mga page na wala sa wikang nababasa mo.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 item}one{# item}other{# na item}}</translation>
 <translation id="5904093760909470684">Configuration ng Proxy</translation>
 <translation id="5906065664303289925">Address ng hardware:</translation>
 <translation id="5910363049092958439">I-sa&amp;ve ang Imahe Bilang...</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb
index 4a47240..21ccbfa 100644
--- a/chrome/app/resources/generated_resources_fr.xtb
+++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Accéder à n'importe lequel de ces appareils USB</translation>
 <translation id="1038168778161626396">Chiffrer seulement</translation>
 <translation id="1038842779957582377">Nom inconnu</translation>
-<translation id="1040931876666128942">Notifications WebUsb</translation>
 <translation id="1042174272890264476">Votre ordinateur est fourni avec la bibliothèque RLZ de <ph name="SHORT_PRODUCT_NAME" />. RLZ attribue un tag non unique (et qui n'identifie pas personnellement les internautes) afin de mesurer les recherches et l'utilisation de <ph name="SHORT_PRODUCT_NAME" /> générées par une campagne de promotion spécifique. Ces libellés s'affichent parfois dans les requêtes de recherche Google dans <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285">Une demande de stockage permanent de données volumineuses sur votre appareil a été envoyée à partir de <ph name="URL" />.</translation>
 <translation id="1045157690796831147">Translittération (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">Les nouveaux paramètres des cookies seront appliqués quand vous aurez actualisé la page.</translation>
 <translation id="14720830734893704">Activer la compatibilité avec le clavier virtuel</translation>
 <translation id="1474339897586437869">Le fichier "<ph name="FILENAME" />" n'a pas été importé, car l'espace disponible sur Google Drive est insuffisant.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 mot de passe}one{# mot de passe}other{# mots de passe}}</translation>
 <translation id="1476949146811612304">Définir le moteur de recherche à utiliser pour les recherches effectuées depuis l'<ph name="BEGIN_LINK" />Omnibox<ph name="END_LINK" /> (barre d'adresse et de recherche)</translation>
 <translation id="1477301030751268706">Cache du jeton de l'API Identity</translation>
 <translation id="1478340334823509079">Détails : <ph name="FILE_NAME" /></translation>
@@ -926,6 +924,7 @@
 <translation id="2326606747676847821">Navigation privée</translation>
 <translation id="2326931316514688470">&amp;Actualiser l'application</translation>
 <translation id="2327492829706409234">Activer l'application</translation>
+<translation id="2329597144923131178">Connectez-vous pour synchroniser favoris, historique, mots de passe et autres sur vos appareils. </translation>
 <translation id="2332131598580221120">Afficher dans la boutique</translation>
 <translation id="2332742915001411729">Rétablir le niveau de zoom par défaut</translation>
 <translation id="2335122562899522968">Cette page place des cookies.</translation>
@@ -949,7 +948,6 @@
 <translation id="2359808026110333948">Continuer</translation>
 <translation id="236128817791440714">Recommandé : Configurer Smart Lock pour Android</translation>
 <translation id="236141728043665931">Toujours bloquer l'accès au micro</translation>
-<translation id="2365626167708453863">Choisir un compte de votre Google Smart Lock</translation>
 <translation id="2367972762794486313">Afficher les applications</translation>
 <translation id="2368075211218459617">Activer la recherche contextuelle</translation>
 <translation id="2370882663124746154">Activer le mode Pinyin double</translation>
@@ -2661,7 +2659,6 @@
 <translation id="4780374166989101364">Cette fonctionnalité active les API des extensions expérimentales. Notez que vous ne pouvez pas mettre en ligne des extensions qui font appel aux API expérimentales dans la galerie d'extensions.</translation>
 <translation id="4781787911582943401">Zoom avant</translation>
 <translation id="4782449893814226250">Une demande d'autorisation a été envoyée à tes parents pour la consultation de cette page.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 Ko}one{# Ko}other{# Ko}}</translation>
 <translation id="4784330909746505604">Présentation PowerPoint</translation>
 <translation id="4785040501822872973">Cet ordinateur va être réinitialisé dans <ph name="LOGOUT_TIME_LEFT" /> secondes.
 Pour poursuivre l'exploration, appuyez sur n'importe quelle touche.</translation>
@@ -3192,7 +3189,6 @@
 <translation id="5527474464531963247">Vous pouvez également sélectionner un autre réseau.</translation>
 <translation id="5527963985407842218">Déclencher le mode lecteur</translation>
 <translation id="5528368756083817449">Gestionnaire de favoris</translation>
-<translation id="5529098031581368697">Le fond d'écran actuel a été défini par <ph name="APP_NAME" />.</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Raccourcis globaux</translation>
 <translation id="5533555070048896610">Translittération (namaste → नमस्ते)</translation>
@@ -3309,7 +3305,6 @@
 <translation id="5702898740348134351">Modifi&amp;er les moteurs de recherche...</translation>
 <translation id="5703594190584829406">Affiche les suggestions de saisie automatique au-dessus du clavier, plutôt que dans une liste déroulante.</translation>
 <translation id="5704272569086782895">Activer la rastérisation GPU par thread</translation>
-<translation id="570544101664452060">Notifications WebUsb expérimentales</translation>
 <translation id="5706551819490830015">Gérer les adresses de facturation…</translation>
 <translation id="5707185214361380026">Échec du chargement de l'extension depuis :</translation>
 <translation id="5707604204219538797">Mot suivant</translation>
@@ -3458,7 +3453,6 @@
 <translation id="5900302528761731119">Photo du profil Google</translation>
 <translation id="5900623698597156974">Une requête de secours TLS 1.0 a permis d'établir une liaison avec le serveur. Cependant, nous n'acceptons plus les requêtes de secours TLS 1.0. Le serveur doit être mis à jour pour correctement mettre en œuvre la négociation des versions et pour assurer la compatibilité dans l'idéal avec TLS 1.2.</translation>
 <translation id="590253956165195626">Me proposer de traduire les pages qui sont écrites dans une langue que je ne connais pas</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 élément}one{# élément}other{# éléments}}</translation>
 <translation id="5904093760909470684">Configuration du proxy</translation>
 <translation id="5906065664303289925">Adresse du matériel :</translation>
 <translation id="5910363049092958439">En&amp;registrer l'image sous...</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb
index 3e7a872..2b865fa 100644
--- a/chrome/app/resources/generated_resources_gu.xtb
+++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">આ USB ઉપકરણોમાંથી કોઈપણ ઍક્સેસ કરો</translation>
 <translation id="1038168778161626396">ફક્ત ચિહ્નિત કરો</translation>
 <translation id="1038842779957582377">અજ્ઞાત નામ</translation>
-<translation id="1040931876666128942">WebUsb સૂચનાઓ.</translation>
 <translation id="1042174272890264476">તમારા કમ્પ્યુટરની સાથે <ph name="SHORT_PRODUCT_NAME" /> ની RLZ લાઇબ્રેરી બિલ્ટ ઇન પણ આવે છે. RLZ વિશેષ પ્રચારાત્મક ઝુંબેશ દ્વારા ચલાવવામાં આવતી શોધ અને <ph name="SHORT_PRODUCT_NAME" /> ઉપયોગને માપવા માટે બિન-અદ્વિતીય, બિન-વ્યક્તિગત રૂપે ઓળખી શકાય તેવા ટૅગ સોંપે છે. આ લેબલ્સ કેટલીકવાર <ph name="PRODUCT_NAME" /> માં Google શોધ ક્વેરીઝમાં દેખાય છે.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> તમારા ઉપકરણ પર કાયમી ધોરણે વિશાળ ડેટા સ્ટોર કરવા માંગે છે.</translation>
 <translation id="1045157690796831147">લિવ્યંતરણ (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">નવી કૂકી સેટિંગ્સ પૃષ્ઠ ફરીથી લોડ કર્યા પછી પ્રભાવમાં આવશે.</translation>
 <translation id="14720830734893704">વર્ચ્યુઅલ કીબોર્ડ સમર્થનને સક્ષમ કરો</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" ને અપલોડ કરવામાં આવી ન હતી. તમારી Google ડ્રાઇવમાં પૂરતી ખાલી જગ્યા નથી.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 પાસવર્ડ}one{# પાસવર્ડ}other{# પાસવર્ડ}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" /> થી શોધ કરતી વખતે કયા શોધ એંજીનનો ઉપયોગ કરવો તે સેટ કરો.</translation>
 <translation id="1477301030751268706">ઓળખ API ટોકન કેશ</translation>
 <translation id="1478340334823509079">વિગતો: <ph name="FILE_NAME" /></translation>
@@ -924,6 +922,7 @@
 <translation id="2326606747676847821">છુપામાં જાઓ</translation>
 <translation id="2326931316514688470">એપ્લિકેશન &amp;ફરીથી લોડ કરો</translation>
 <translation id="2327492829706409234">એપ્લિકેશન સક્ષમ કરો</translation>
+<translation id="2329597144923131178">તમારા તમામ ઉપકરણો પર તમારા બુકમાર્ક્સ, ઇતિહાસ, પાસવર્ડ્સ અને અન્ય સેટિંગ્સ મેળવવા માટે સાઇન ઇન કરો.</translation>
 <translation id="2332131598580221120">દુકાનમાં જુઓ</translation>
 <translation id="2332742915001411729">ડિફોલ્ટ પર ફરીથી સેટ કરો</translation>
 <translation id="2335122562899522968">આ પૃષ્ઠ કૂકીઝ સેટ કરે છે.</translation>
@@ -947,7 +946,6 @@
 <translation id="2359808026110333948">ચાલુ રાખો</translation>
 <translation id="236128817791440714">ભલામણ કરેલ: Android માટે Smart Lock સેટ કરો</translation>
 <translation id="236141728043665931">માઇક્રોફોનની ઍક્સેસને હંમેશા અવરોધિત કરો</translation>
-<translation id="2365626167708453863">તમારા Google Smart Lock થી એક એકાઉન્ટ પસંદ કરો</translation>
 <translation id="2367972762794486313">એપ્લિકેશનો બતાવો</translation>
 <translation id="2368075211218459617">સાંદર્ભિક શોધને સક્ષમ કરો.</translation>
 <translation id="2370882663124746154">Double-Pinyin મોડને સક્ષમ કરો </translation>
@@ -2663,7 +2661,6 @@
 <translation id="4780374166989101364">પ્રાયોગિક એક્સ્ટેંશન્સ API ને સક્ષમ કરે છે. નોંધ રાખો કે એક્સ્ટેંશન ગેલેરીથી તમે પ્રાયોગિક API નો ઉપયોગ કરતા એક્સ્ટેંશન્સને અપલોડ કરી શકતા નથી.</translation>
 <translation id="4781787911582943401">સ્ક્રીનનું ઝૂમ વધારો</translation>
 <translation id="4782449893814226250">તમે આ પૃષ્ઠની મુલાકાત લો તે ઠીક છે કે કેમ તેવું તમે તમારા માતાપિતાને પૂછ્યું.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}one{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint પ્રસ્તુતિ</translation>
 <translation id="4785040501822872973">આ કમ્પ્યુટર <ph name="LOGOUT_TIME_LEFT" /> સેકંડમાં ફરીથી સેટ થશે.
 અન્વેષણ ચાલુ રાખવા માટે કોઈપણ કી દબાવો.</translation>
@@ -3192,7 +3189,6 @@
 <translation id="5527474464531963247">તમે બીજું નેટવર્ક પણ પસંદ કરી શકો છો. </translation>
 <translation id="5527963985407842218">રીડર મોડ ટ્રિગર કરી રહ્યું છે</translation>
 <translation id="5528368756083817449">બુકમાર્ક વ્યવસ્થાપક</translation>
-<translation id="5529098031581368697">'<ph name="APP_NAME" />' દ્વારા વર્તમાન વૉલપેપર સેટ કરવામાં આવ્યું છે</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">વૈશ્વિક</translation>
 <translation id="5533555070048896610">લિવ્યંતરણ (namaste → नमस्ते)</translation>
@@ -3308,7 +3304,6 @@
 <translation id="5702898740348134351">&amp;શોધ એન્જિન્સ સંપાદિત કરો...</translation>
 <translation id="5703594190584829406">ડ્રોપડાઉનને બદલે કીબોર્ડની ટોચ પર સ્વતઃભરણ સૂચનો દર્શાવે છે.</translation>
 <translation id="5704272569086782895">GPU રાસ્ટરાઇઝેશનને સક્ષમ કરો.</translation>
-<translation id="570544101664452060">પ્રાયોગિક WebUsb સૂચનાઓ.</translation>
 <translation id="5706551819490830015">બિલિંગ સરનામાં સંચાલિત કરો...</translation>
 <translation id="5707185214361380026">અહીંથી એક્સ્ટેન્શનને લોડ કરવામાં નિષ્ફળ:</translation>
 <translation id="5707604204219538797">આગલો શબ્દ</translation>
@@ -3457,7 +3452,6 @@
 <translation id="5900302528761731119">Google પ્રોફાઇલ ફોટો</translation>
 <translation id="5900623698597156974">TLS 1.0 ફૉલબેક સર્વર સાથે હેન્ડશેક કરવામાં સમર્થ હતું, પરંતુ અમે હવે TLS 1.0 ફૉલબેક્સ સ્વીકારતાં નથી. સંસ્કરણ નિગોશિએશનને ઠીકથી લાગુ કરવા તથા TLS 1.2 ને અગ્રીમપણે સમર્થિત કરવા માટે સર્વરને અપડેટ કરવાની જરૂર છે.</translation>
 <translation id="590253956165195626">તમે વાંચો છો તે ભાષામાં ન હોય તેવા પૃષ્ઠોના અનુવાદની ઓફર કરો.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 આઇટમ}one{# આઇટમ}other{# આઇટમ}}</translation>
 <translation id="5904093760909470684">પ્રોક્સી ગોઠવણી</translation>
 <translation id="5906065664303289925">હાર્ડવેર સરનામું:</translation>
 <translation id="5910363049092958439">છબીને આ રૂપે સા&amp;ચવો...</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb
index e2e70580..d185cdbb 100644
--- a/chrome/app/resources/generated_resources_hi.xtb
+++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">इनमें से कोई भी USB डिवाइस ऐक्‍सेस करें</translation>
 <translation id="1038168778161626396">केवल कूटलेखन</translation>
 <translation id="1038842779957582377">अज्ञात नाम</translation>
-<translation id="1040931876666128942">WebUsb नोटिफिकेशन.</translation>
 <translation id="1042174272890264476">आपके कंप्यूटर में <ph name="SHORT_PRODUCT_NAME" /> की RLZ लाइब्रेरी भी अंतर्निहित आती है. RLZ एक गैर-अद्वितीय, गैर-व्यक्तिगत रूप से पहचाने जाने योग्य टैग असाइन करता है ताकि खोजों तथा किसी विशिष्ट प्रचार अभियान द्वारा संचालित <ph name="SHORT_PRODUCT_NAME" /> उपयोग को मापा जा सके. कभी-कभी ये लेबल <ph name="PRODUCT_NAME" /> में Google खोज क्वेरी में दिखाई देते हैं.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> स्थायी रूप से आपके डिवाइस पर बड़ा डेटा संगृहीत करना चाहता है.</translation>
 <translation id="1045157690796831147">लिप्यंतरण (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">पृष्ठ के फिर से लोड होने के बाद नई कुकी सेटिंग प्रभावी होगी.</translation>
 <translation id="14720830734893704">आभासी कीबोर्ड सहायता सक्षम करें.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" को अपलोड नहीं किया गया. आपकी Google डिस्क में पर्याप्त जगह नहीं है.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 पासवर्ड}one{# पासवर्ड}other{# पासवर्ड}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />ऑम्निबॉक्‍स<ph name="END_LINK" /> से खोजते समय उपयोग किया जाने वाला खोज इंजन सेट करें.</translation>
 <translation id="1477301030751268706">पहचान API टोकन संचय</translation>
 <translation id="1478340334823509079">विवरण: <ph name="FILE_NAME" /></translation>
@@ -932,6 +930,7 @@
 <translation id="2326606747676847821">गुप्त मोड में जाएं</translation>
 <translation id="2326931316514688470">&amp;ऐप पुन: लोड करें</translation>
 <translation id="2327492829706409234">ऐप्स  सक्षम करें</translation>
+<translation id="2329597144923131178">सभी डिवाइसों पर बुकमार्क, इतिहास, पासवर्ड और अन्‍य सेटिंग प्राप्‍त करने हेतु प्रवेश करें.</translation>
 <translation id="2332131598580221120">स्टोर में देखें</translation>
 <translation id="2332742915001411729">डिफ़ॉल्ट पर रीसेट करें</translation>
 <translation id="2335122562899522968">यह पृष्ठ कुकी सेट करता है.</translation>
@@ -955,7 +954,6 @@
 <translation id="2359808026110333948">जारी रखें</translation>
 <translation id="236128817791440714">अनुशंसित: Android के लिए Smart Lock सेट करें</translation>
 <translation id="236141728043665931">माइक्रोफ़ोन एक्सेस हमेशा अवरुद्ध करें</translation>
-<translation id="2365626167708453863">अपने Google Smart Lock से कोई खाता चुनें</translation>
 <translation id="2367972762794486313">ऐप्स  दिखाएं</translation>
 <translation id="2368075211218459617">प्रासंगिक खोज सक्षम करें.</translation>
 <translation id="2370882663124746154">डबल-पिनयिन मोड सक्षम करें</translation>
@@ -2669,7 +2667,6 @@
 <translation id="4780374166989101364">प्रायोगिक एक्सटेंशन API सक्षम करता है. ध्यान दें कि एक्सटेंशन गैलरी आपको उन एक्सटेशन को अपलोड करने की अनुमति नहीं देत्ती है, जो प्रायोगिक API का उपयोग करते हैं.</translation>
 <translation id="4781787911582943401">स्क्रीन ज़ूम इन करें</translation>
 <translation id="4782449893814226250">आपने अपने अभिभावकों से पूछा था कि इस पृष्‍ठ पर जाना ठीक है या नहीं.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}one{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint प्रस्तुतिकरण</translation>
 <translation id="4785040501822872973">यह कंप्यूटर <ph name="LOGOUT_TIME_LEFT" /> सेकंड में रीसेट हो जाएगा.
 अन्वेषण जारी रखने के लिए कोई भी कुंजी दबाएं.</translation>
@@ -3200,7 +3197,6 @@
 <translation id="5527474464531963247">आप किसी दूसरे नेटवर्क का चयन भी कर सकते हैं.</translation>
 <translation id="5527963985407842218">रीडर मोड ट्रिगर करना</translation>
 <translation id="5528368756083817449">Bookmark manager</translation>
-<translation id="5529098031581368697">वर्तमान वॉलपेपर '<ph name="APP_NAME" />' द्वारा सेट किया गया है</translation>
 <translation id="5531274207066050939">Google पेमेंट्स</translation>
 <translation id="5532223876348815659">वैश्विक</translation>
 <translation id="5533555070048896610">लिप्यंतरण (namaste → नमस्ते)</translation>
@@ -3315,7 +3311,6 @@
 <translation id="5702898740348134351">खोज इंजन &amp;संपादित करें...</translation>
 <translation id="5703594190584829406">किसी ड्रॉपडाउन के बजाय कीबोर्ड के शीर्ष पर स्वतः-भरण सुझाव दिखाता है.</translation>
 <translation id="5704272569086782895">थ्रेड किया गया GPU रेस्‍टराइज़ेशन सक्षम करें.</translation>
-<translation id="570544101664452060">प्रयोगात्‍मक WebUsb नोटिफिकेशन.</translation>
 <translation id="5706551819490830015">बिलिंग पते प्रबंधित करें...</translation>
 <translation id="5707185214361380026">इससे एक्सटेंशन लोड करने में विफल:</translation>
 <translation id="5707604204219538797">अगला शब्‍द</translation>
@@ -3464,7 +3459,6 @@
 <translation id="5900302528761731119">Google प्रोफ़ाइल फ़ोटो</translation>
 <translation id="5900623698597156974">एक TLS 1.0 फ़ॉलबैक सर्वर से संपर्क कर सका था, लेकिन अब हम TLS 1.0 फ़ॉलबैक स्‍वीकार नहीं करते. वर्शन निर्धारण को सही तरीके से क्रियान्‍वित करने और संभावित रूप से TLS 1.2 का समर्थन करने के लिए सर्वर को अपडेट किया जाना आवश्‍यक है.</translation>
 <translation id="590253956165195626">ऐसे पृष्ठों का अनुवाद करना ऑफ़र करें जो आपके द्वारा पढ़ी जाने वाली भाषा में नहीं हैं.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 आइटम}one{# आइटम}other{# आइटम}}</translation>
 <translation id="5904093760909470684">प्रॉक्सी कॉन्फ़िगरेशन</translation>
 <translation id="5906065664303289925">हार्डवेयर पता:</translation>
 <translation id="5910363049092958439">इस रूप में चित्र स&amp;हेजें...</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb
index 72af213..765a78f 100644
--- a/chrome/app/resources/generated_resources_hr.xtb
+++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">pristupiti bilo kojem od ovih USB uređaja</translation>
 <translation id="1038168778161626396">Samo za šifriranje</translation>
 <translation id="1038842779957582377">nepoznati naziv</translation>
-<translation id="1040931876666128942">Obavijesti WebUsba.</translation>
 <translation id="1042174272890264476">Vaše računalo ima ugrađenu RLZ biblioteku preglednika <ph name="SHORT_PRODUCT_NAME" />. RLZ dodjeljuje nejedinstvenu oznaku koja ne može poslužiti za osobnu identifikaciju za mjerenje pretraživanja i upotrebu proizvoda <ph name="SHORT_PRODUCT_NAME" /> potaknutu određenom promotivnom kampanjom. Te se oznake ponekad prikazuju u upitima Google pretraživanja u pregledniku <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> želi trajno pohraniti veliku količinu podataka na vaš uređaj.</translation>
 <translation id="1045157690796831147">transliteracija (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Nove postavke kolačića postat će aktivne nakon ponovnog učitavanja stranice.</translation>
 <translation id="14720830734893704">Omogućuje podršku za virtualnu tipkovnicu.</translation>
 <translation id="1474339897586437869">Datoteka "<ph name="FILENAME" />" nije prenesena. Nema dovoljno slobodnog prostora na Google disku.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 zaporka}one{# zaporka}few{# zaporke}other{# zaporki}}</translation>
 <translation id="1476949146811612304">Postavljanje odabira tražilica koje će se upotrebljavati kod pretraživanja iz <ph name="BEGIN_LINK" />višenamjenskog okvira<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Predmemoriranje oznake API-ja Identity</translation>
 <translation id="1478340334823509079">Pojedinosti: <ph name="FILE_NAME" /></translation>
@@ -919,6 +917,7 @@
 <translation id="2326606747676847821">Anonimni način</translation>
 <translation id="2326931316514688470">&amp;Ponovo učitaj aplikaciju</translation>
 <translation id="2327492829706409234">Omogući aplikaciju</translation>
+<translation id="2329597144923131178">Prijavite se da biste imali svoje oznake, povijest, zaporke i druge postavke na svim svojim uređajima.</translation>
 <translation id="2332131598580221120">Prikaži u Web-trgovini</translation>
 <translation id="2332742915001411729">Vrati na zadano</translation>
 <translation id="2335122562899522968">Ova stranica postavila je kolačiće.</translation>
@@ -942,7 +941,6 @@
 <translation id="2359808026110333948">Nastavi</translation>
 <translation id="236128817791440714">Preporučeno: postavite Smart Lock za Android</translation>
 <translation id="236141728043665931">Uvijek blokiraj pristup mikrofonu</translation>
-<translation id="2365626167708453863">Odaberite račun sa svojeg Google Smart Locka</translation>
 <translation id="2367972762794486313">Prikaz aplikacija</translation>
 <translation id="2368075211218459617">Omogućite kontekstualno pretraživanje.</translation>
 <translation id="2370882663124746154">Omogući način Double-Pinyin</translation>
@@ -2651,7 +2649,6 @@
 <translation id="4780374166989101364">Omogućuje API-je eksperimentalnih proširenja. Napominjemo da galerija proširenja ne dopušta prijenos proširenja koja upotrebljavaju eksperimentalne API-je.</translation>
 <translation id="4781787911582943401">Uvećavanje zaslona</translation>
 <translation id="4782449893814226250">Pitao si roditelje smiješ li otvoriti tu stranicu.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}one{# KB}few{# KB}other{# KB}}</translation>
 <translation id="4784330909746505604">PowerPointova prezentacija</translation>
 <translation id="4785040501822872973">Ovo će se računalo poništiti za <ph name="LOGOUT_TIME_LEFT" /> s.
 Pritisnite bilo koju tipku da biste nastavili istraživati.</translation>
@@ -3182,7 +3179,6 @@
 <translation id="5527474464531963247">Također možete odabrati neku drugu mrežu.</translation>
 <translation id="5527963985407842218">Pokretanje načina čitača</translation>
 <translation id="5528368756083817449">Upravitelj oznaka</translation>
-<translation id="5529098031581368697">Trenutačnu pozadinu postavila je aplikacija "<ph name="APP_NAME" />"</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Globalno</translation>
 <translation id="5533555070048896610">transliteracija (namaste → नमस्ते)</translation>
@@ -3298,7 +3294,6 @@
 <translation id="5702898740348134351">&amp;Uredi tražilice...</translation>
 <translation id="5703594190584829406">Prikazuje prijedloge Automatskog popunjavanja pri vrhu tipkovnice, a ne na padajućem izborniku.</translation>
 <translation id="5704272569086782895">Omogući GPU rasterizaciju u nizovima.</translation>
-<translation id="570544101664452060">Eksperimentalne obavijesti WebUsb-a.</translation>
 <translation id="5706551819490830015">Upravljanje adresama za naplatu...</translation>
 <translation id="5707185214361380026">Nije učitano proširenje s lokacije:</translation>
 <translation id="5707604204219538797">Sljedeća riječ</translation>
@@ -3445,7 +3440,6 @@
 <translation id="5900302528761731119">Fotografija Google profila</translation>
 <translation id="5900623698597156974">Rezervni TLS 1.0 uspio se rukovati s poslužiteljem, ali više ne prihvaćamo rezervne protokole TLS 1.0. Poslužitelj se mora ažurirati da bi pravilno primjenjivao pregovaranje o verziji i po mogućnosti podržavao TLS 1.2.</translation>
 <translation id="590253956165195626">Ponudi prijevod stranica koje nisu na jeziku koji čitam.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 stavka}one{# stavka}few{# stavke}other{# stavki}}</translation>
 <translation id="5904093760909470684">Konfiguracija proxyja</translation>
 <translation id="5906065664303289925">Hardverska adresa:</translation>
 <translation id="5910363049092958439">Sp&amp;remi sliku kao...</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb
index aa8693ed..306a544e 100644
--- a/chrome/app/resources/generated_resources_hu.xtb
+++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Az alábbi USB-eszközök bármelyikének elérése</translation>
 <translation id="1038168778161626396">Csak titkosítás</translation>
 <translation id="1038842779957582377">Ismeretlen név</translation>
-<translation id="1040931876666128942">WebUsb-értesítések.</translation>
 <translation id="1042174272890264476">Számítógépe a <ph name="SHORT_PRODUCT_NAME" /> RLZ-könyvtárát is tartalmazza beépítve. Az RLZ egy nem egyedi, személy szerinti azonosításra nem alkalmas címkét rendel hozzá a keresések és a <ph name="SHORT_PRODUCT_NAME" /> használatának egy adott promóciós kampány keretein belüli felméréséhez. Ezek a címkék időnként a <ph name="PRODUCT_NAME" /> Google-keresési lekérdezéseiben is feltűnnek.</translation>
 <translation id="1042574203789536285">A(z) <ph name="URL" /> webhely állandó jelleggel nagyméretű adatokat akar tárolni az eszközén.</translation>
 <translation id="1045157690796831147">Átírás (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Az új cookie-beállítások az oldal ismételt betöltése után lépnek életbe.</translation>
 <translation id="14720830734893704">Virtuális billentyűzet támogatásának engedélyezése.</translation>
 <translation id="1474339897586437869">A(z) „<ph name="FILENAME" />” feltöltése nem történt meg. Nincs elegendő szabad terület a Google Drive-on.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 jelszó}other{# jelszó}}</translation>
 <translation id="1476949146811612304">Állítsa be, hogy a böngésző melyik keresőmotort használja, amikor Ön a <ph name="BEGIN_LINK" />cím- és keresősávból<ph name="END_LINK" /> keres.</translation>
 <translation id="1477301030751268706">Azonosítási API token-gyorsítótára</translation>
 <translation id="1478340334823509079">Részletek: <ph name="FILE_NAME" /></translation>
@@ -575,7 +573,7 @@
 <translation id="1793119619663054394">Biztosan törli a(z) „<ph name="PROFILE_NAME" />” profilt és annak összes Chrome-adatát erről a számítógépről? A művelet nem vonható vissza.</translation>
 <translation id="179767530217573436">elmúlt 4 hét</translation>
 <translation id="180035236176489073">Online kell lennie a fájlok eléréséhez.</translation>
-<translation id="1801298019027379214">Helytelen PIN kód, kérjük, próbálja meg újra. Fennmaradó próbálkozások száma: <ph name="TRIES_COUNT" /></translation>
+<translation id="1801298019027379214">Helytelen PIN-kód, kérjük, próbálja meg újra. Fennmaradó próbálkozások száma: <ph name="TRIES_COUNT" /></translation>
 <translation id="1801827354178857021">Időszak</translation>
 <translation id="1803133642364907127">Bővítménytartalom ellenőrzése</translation>
 <translation id="1804251416207250805">Hiperlink-ellenőrző pingek küldésének letiltása.</translation>
@@ -922,6 +920,7 @@
 <translation id="2326606747676847821">Váltás inkognitóra</translation>
 <translation id="2326931316514688470">Alkalmazás új&amp;ratöltése</translation>
 <translation id="2327492829706409234">Alkalmazás engedélyezése</translation>
+<translation id="2329597144923131178">Jelentkezzen be, hogy könyvjelzőit, előzményeit, jelszavait és más beállításait az összes eszközén elérje.</translation>
 <translation id="2332131598580221120">Megtekintés az áruházban</translation>
 <translation id="2332742915001411729">Visszaállítás az alapértékre</translation>
 <translation id="2335122562899522968">Ez az oldal cookie-kat állít be.</translation>
@@ -945,7 +944,6 @@
 <translation id="2359808026110333948">Folytatás</translation>
 <translation id="236128817791440714">Ajánlott: a Smart Lock beállítása Androidon</translation>
 <translation id="236141728043665931">Mikrofon elérésének állandó tiltása</translation>
-<translation id="2365626167708453863">Fiók kiválasztása a Google Smart Lock funkcióból</translation>
 <translation id="2367972762794486313">Alkalmazások megjelenítése</translation>
 <translation id="2368075211218459617">A Kontextusfüggő keresés engedélyezése.</translation>
 <translation id="2370882663124746154">A dupla pinjin beviteli mód engedélyezése</translation>
@@ -1702,7 +1700,7 @@
 <translation id="3382073616108123819">Hoppá! A rendszer nem tudta megállapítani az eszközazonosítókat ehhez az eszközhöz.</translation>
 <translation id="3384773155383850738">Maximális javaslatszám</translation>
 <translation id="338583716107319301">Elválasztó</translation>
-<translation id="3391392691301057522">Régi PIN kód:</translation>
+<translation id="3391392691301057522">Régi PIN-kód:</translation>
 <translation id="3391716558283801616">7. lap</translation>
 <translation id="3392020134425442298">Rosszindulatú fájl helyreállítása</translation>
 <translation id="3393716657345709557">A kért bejegyzés nem található a gyorsítótárban.</translation>
@@ -2232,7 +2230,7 @@
 <translation id="4110559665646603267">Fókuszálás a polcra</translation>
 <translation id="4112917766894695549">Ezeket a beállításokat a rendszergazdája kényszeríti ki.</translation>
 <translation id="4114360727879906392">Előző ablak</translation>
-<translation id="4114470632216071239">SIM-kártya zárolása (PIN kód bekérése mobiladatok használatához)</translation>
+<translation id="4114470632216071239">SIM-kártya zárolása (PIN-kód bekérése mobiladatok használatához)</translation>
 <translation id="4114955900795884390">Nincs megfelelő beépülő modul a tartalom megjelenítéséhez.</translation>
 <translation id="4116663294526079822">Mindig engedélyezze ezen az oldalon</translation>
 <translation id="411666854932687641">Saját memória</translation>
@@ -2651,7 +2649,6 @@
 <translation id="4780374166989101364">Engedélyezi a kísérleti bővítmény-API-kat. Figyelem! A bővítménygaléria nem teszi lehetővé, hogy kísérleti API-kat használó bővítményeket töltsön fel.</translation>
 <translation id="4781787911582943401">Képernyő nagyítása</translation>
 <translation id="4782449893814226250">Megkérdezted a szüleidet, hogy meg szabad-e látogatnod ezt az oldalt.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint-bemutató</translation>
 <translation id="4785040501822872973">Ez a számítógép <ph name="LOGOUT_TIME_LEFT" /> másodperc múlva újraindul. Bármely gomb lenyomásával folytathatja a felfedezését.</translation>
 <translation id="4786993863723020412">Gyorsítótár-olvasási hiba</translation>
@@ -2838,7 +2835,7 @@
 <translation id="5061188462607594407">Tegye biztonságossá <ph name="PHONE_TYPE" /> telefonját a folytatáshoz</translation>
 <translation id="5061708541166515394">Kontraszt</translation>
 <translation id="5062930723426326933">A bejelentkezés nem sikerült. Kérjük, kapcsolódjon az internethez, majd próbálja újra.</translation>
-<translation id="5063180925553000800">Új PIN kód:</translation>
+<translation id="5063180925553000800">Új PIN-kód:</translation>
 <translation id="5067867186035333991">Kérdezzen rá, ha a(z) <ph name="HOST" /> hozzá szeretne férni a mikrofonhoz</translation>
 <translation id="5068787915627988398">Ha be van kapcsolva, bármilyen eredet a felhasználó megkérdezése nélkül használhat csatlakoztatott WebUSB-eszközöket.</translation>
 <translation id="507075806566596212">A <ph name="DEVICE_TYPE" /> Google-regisztrációjára készül, amivel engedélyezi az eszköz távoli helymeghatározásának, törlésének és zárolásának lehetőségét. A művelet végrehajtásához újra kell indítania az eszközt. Folytatja?</translation>
@@ -2846,7 +2843,7 @@
 <translation id="5074318175948309511">Előfordulhat, hogy az új beállítások életbe lépéséhez az oldal újratöltése szükséges.</translation>
 <translation id="5075306601479391924">Felhasználói kézmozdulatok megkövetelésének kikapcsolása a médiaelemek lejátszásához. Ennek aktiválásával engedélyezi az automatikus lejátszás működését.</translation>
 <translation id="5078638979202084724">Összes lap hozzáadása a könyvjelzőkhöz</translation>
-<translation id="5078796286268621944">Helytelen PIN kód</translation>
+<translation id="5078796286268621944">Helytelen PIN-kód</translation>
 <translation id="5081055027309504756">Seccomp-BPF sandbox</translation>
 <translation id="5085162214018721575">Frissítések keresése</translation>
 <translation id="5086082738160935172">HID</translation>
@@ -3181,7 +3178,6 @@
 <translation id="5527474464531963247">Másik hálózatot is választhat.</translation>
 <translation id="5527963985407842218">Olvasási mód aktiválása</translation>
 <translation id="5528368756083817449">Könyvjelzőkezelő</translation>
-<translation id="5529098031581368697">Az aktuális háttérképet a(z) „<ph name="APP_NAME" />” állította be</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Általános</translation>
 <translation id="5533555070048896610">Átírás (namaste → नमस्ते)</translation>
@@ -3197,7 +3193,7 @@
         Engedélyezés esetén a document.scrollingElement értéke document.documentElement; letiltása esetén pedig document.body (szigorú módú oldalaknál).</translation>
 <translation id="5550431144454300634">Bevitel automatikus javítása</translation>
 <translation id="5553089923092577885">Tanúsítvány-irányelv leképezések</translation>
-<translation id="5553784454066145694">Új PIN kód választása</translation>
+<translation id="5553784454066145694">Új PIN-kód választása</translation>
 <translation id="5554489410841842733">Ez az ikon akkor látható, ha a bővítmény tehet valamit az aktuális oldalon.</translation>
 <translation id="5554573843028719904">Egyéb Wi-Fi hálózat...</translation>
 <translation id="5554720593229208774">E-mail tanúsítványkibocsátó</translation>
@@ -3298,7 +3294,6 @@
 <translation id="5702898740348134351">&amp;Keresők szerkesztése...</translation>
 <translation id="5703594190584829406">Az Automatikus kitöltés javaslatait a billentyűzet tetején jeleníti meg, nem pedig egy legördülő menüben.</translation>
 <translation id="5704272569086782895">Több szálon futó GPU-raszterizálás engedélyezése.</translation>
-<translation id="570544101664452060">Kísérleti WebUsb-értesítések.</translation>
 <translation id="5706551819490830015">Számlázási címek kezelése...</translation>
 <translation id="5707185214361380026">Nem sikerült a bővítmény betöltése innen:</translation>
 <translation id="5707604204219538797">Következő szó</translation>
@@ -3445,7 +3440,6 @@
 <translation id="5900302528761731119">Google-profil fotó</translation>
 <translation id="5900623698597156974">Egy TLS 1.0-tartalék fel tudta venni a kapcsolatot a szerverrel, de már nem fogadjuk el a TLS 1.0-tartalékokat. A szervert frissíteni kell, hogy megfelelően hajthassa végre a verzió egyeztetést és ideális esetben a TLS 1.2 verziót támogassa</translation>
 <translation id="590253956165195626">Kínálja fel az Ön által nem ismert nyelven írt oldalak fordítását.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 elem}other{# elem}}</translation>
 <translation id="5904093760909470684">Proxykonfiguráció</translation>
 <translation id="5906065664303289925">Hardvercím:</translation>
 <translation id="5910363049092958439">Ké&amp;p mentése másként...</translation>
@@ -3636,7 +3630,7 @@
 <translation id="6196207969502475924">Hangalapú keresés</translation>
 <translation id="6196854373336333322">A(z) <ph name="EXTENSION_NAME" /> bővítmény átvette az irányítást proxybeállításai felett, ami azt jelenti, hogy a bővítmény minden internetes tevékenységét módosíthatja, feltörheti vagy lehallgathatja. Ha nem biztos benne, hogy miért történt a változás, akkor valószínűleg nem is akarja azt.</translation>
 <translation id="6198102561359457428">Jelentkezzen ki, majd jelentkezzen be újra...</translation>
-<translation id="6198252989419008588">PIN kód megváltoztatása</translation>
+<translation id="6198252989419008588">PIN-kód megváltoztatása</translation>
 <translation id="6199801702437275229">Várakozás a helyinformációkra...</translation>
 <translation id="6200903742087665630">Folyamaton kívüli iframe-ek engedélyezése</translation>
 <translation id="6203231073485539293">Ellenőrizze az internetkapcsolatot</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb
index ab3d3b0..85c08ee 100644
--- a/chrome/app/resources/generated_resources_id.xtb
+++ b/chrome/app/resources/generated_resources_id.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Akses salah satu perangkat USB ini</translation>
 <translation id="1038168778161626396">Khusus Penyandi</translation>
 <translation id="1038842779957582377">nama tidak diketahui</translation>
-<translation id="1040931876666128942">Notifikasi WebUsb</translation>
 <translation id="1042174272890264476">Komputer Anda juga dilengkapi dengan perpustakaan RLZ <ph name="SHORT_PRODUCT_NAME" /> yang tertanam di dalamnya. RLZ menetapkan tag tak unik dan tidak dapat diidentifikasi secara pribadi untuk mengukur penelusuran dan penggunaan <ph name="SHORT_PRODUCT_NAME" /> yang didorong oleh kampanye promosi tertentu. Biasanya label ini muncul di kueri Google Penelusuran di <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> ingin menyimpan data berukuran besar pada perangkat Anda secara permanen.</translation>
 <translation id="1045157690796831147">Transliterasi (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">Setelan cookie baru akan berlaku setelah laman dimuat ulang.</translation>
 <translation id="14720830734893704">Mengaktifkan dukungan keyboard virtual.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" tidak diunggah. Ruang di Google Drive Anda tidak cukup.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 sandi}other{# sandi}}</translation>
 <translation id="1476949146811612304">Menyetel mesin telusur yang digunakan ketika menelusuri dari <ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Cache Token API Identitas</translation>
 <translation id="1478340334823509079">Detail: <ph name="FILE_NAME" /></translation>
@@ -923,6 +921,7 @@
 <translation id="2326606747676847821">Buka Mode Penyamaran</translation>
 <translation id="2326931316514688470">&amp;Muat ulang aplikasi</translation>
 <translation id="2327492829706409234">Aktifkan aplikasi</translation>
+<translation id="2329597144923131178">Masuk untuk mendapatkan bookmark, riwayat, sandi, dan setelan Anda lainnya di semua perangkat.</translation>
 <translation id="2332131598580221120">Lihat di toko</translation>
 <translation id="2332742915001411729">Setel ulang ke default</translation>
 <translation id="2335122562899522968">Laman ini menyetel cookie.</translation>
@@ -946,7 +945,6 @@
 <translation id="2359808026110333948">Lanjut</translation>
 <translation id="236128817791440714">Saran: Siapkan Smart Lock untuk Android</translation>
 <translation id="236141728043665931">Selalu blokir akses mikrofon</translation>
-<translation id="2365626167708453863">Pilih akun dari Google Smart Lock</translation>
 <translation id="2367972762794486313">Tampilkan aplikasi</translation>
 <translation id="2368075211218459617">Aktifkan Penelusuran Kontekstual.</translation>
 <translation id="2370882663124746154">Aktifkan Mode Pinyin Ganda</translation>
@@ -2657,7 +2655,6 @@
 <translation id="4780374166989101364">Aktifkan API ekstensi eksperimental. Perlu diingat bahwa galeri ekstensi tidak mengizinkan Anda mengunggah ekstensi yang menggunakan API eksperimental.</translation>
 <translation id="4781787911582943401">Memperbesar layar</translation>
 <translation id="4782449893814226250">Anda telah meminta izin kepada orang tua untuk mengunjungi laman ini.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}other{# KB}}</translation>
 <translation id="4784330909746505604">Presentasi PowerPoint</translation>
 <translation id="4785040501822872973">Komputer ini akan disetel ulang dalam waktu <ph name="LOGOUT_TIME_LEFT" /> detik.
 Tekan sembarang tombol untuk melanjutkan penjelajahan.</translation>
@@ -3188,7 +3185,6 @@
 <translation id="5527474464531963247">Anda juga dapat memilih jaringan lain.</translation>
 <translation id="5527963985407842218">Pemicu Mode Pembaca</translation>
 <translation id="5528368756083817449">Pengelola Bookmark</translation>
-<translation id="5529098031581368697">Wallpaper saat ini disetel dengan '<ph name="APP_NAME" />'</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Transliterasi (namaste → नमस्ते)</translation>
@@ -3304,7 +3300,6 @@
 <translation id="5702898740348134351">&amp;Edit Mesin Telusur...</translation>
 <translation id="5703594190584829406">Menampilkan saran IsiOtomatis di bagian atas keyboard, bukan di menu tarik-turun.</translation>
 <translation id="5704272569086782895">Aktifkan untaian rasterisasi GPU.</translation>
-<translation id="570544101664452060">Notifikasi eksperimental WebUsb.</translation>
 <translation id="5706551819490830015">Kelola alamat penagihan...</translation>
 <translation id="5707185214361380026">Gagal memuat ekstensi dari:</translation>
 <translation id="5707604204219538797">Kata berikutnya</translation>
@@ -3453,7 +3448,6 @@
 <translation id="5900302528761731119">Foto Google profil</translation>
 <translation id="5900623698597156974">TLS 1.0 fallback dapat menghubungi server, namun kami tidak lagi menerima TLS 1.0 fallback. Server perlu diperbarui agar dapat menerapkan versi negosiasi dengan benar dan lebih mendukung TLS 1.2.</translation>
 <translation id="590253956165195626">Tanya apakah laman yang tidak saya pahami ingin diterjemahkan</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 item}other{# item}}</translation>
 <translation id="5904093760909470684">Konfigurasi Proxy</translation>
 <translation id="5906065664303289925">Alamat perangkat keras:</translation>
 <translation id="5910363049092958439">Sim&amp;pan Gambar Sebagai...</translation>
@@ -3952,7 +3946,7 @@
 <translation id="666541661050183336">Mengurangi prioritas beban sumber daya iframe.</translation>
 <translation id="6666647326143344290">dengan Akun Google Anda</translation>
 <translation id="6667102209320924827">Nonaktifkan kalibrasi warna layar.</translation>
-<translation id="6675665718701918026">Perangkat yang ditunjuk tersambung</translation>
+<translation id="6675665718701918026">Perangkat penunjuk telah tersambung</translation>
 <translation id="6677037229676347494">ID yang diharapkan "<ph name="EXPECTED_ID" />", tapi ID-nya adalah "<ph name="NEW_ID" />".</translation>
 <translation id="6680028776254050810">Alihkan Pengguna</translation>
 <translation id="6681668084120808868">Ambil foto</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb
index 06a464e..8db63c4 100644
--- a/chrome/app/resources/generated_resources_it.xtb
+++ b/chrome/app/resources/generated_resources_it.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Accedi a tutti questi dispositivi USB</translation>
 <translation id="1038168778161626396">Solo crittografia</translation>
 <translation id="1038842779957582377">nome sconosciuto</translation>
-<translation id="1040931876666128942">Notifiche WebUsb.</translation>
 <translation id="1042174272890264476">Sul computer è integrata anche la libreria RLZ di <ph name="SHORT_PRODUCT_NAME" />. RLZ assegna un tag non univoco che non consente l'identificazione personale per valutare le ricerche e l'utilizzo di <ph name="SHORT_PRODUCT_NAME" /> promosso da una determinata campagna promozionale. Talvolta queste etichette vengono visualizzate in query della Ricerca Google in <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> vuole memorizzare in modo permanente grandi quantità di dati sul dispositivo.</translation>
 <translation id="1045157690796831147">Traslitterazione (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Le nuove impostazioni dei cookie avranno effetto una volta ricaricata la pagina.</translation>
 <translation id="14720830734893704">Attiva il supporto della tastiera virtuale.</translation>
 <translation id="1474339897586437869">Impossibile caricare "<ph name="FILENAME" />". Lo spazio disponibile su Google Drive non è sufficiente.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 password}other{# password}}</translation>
 <translation id="1476949146811612304">Imposta il motore di ricerca da utilizzare per le ricerche dalla <ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Cache token dell'API Identity</translation>
 <translation id="1478340334823509079">Dettagli: <ph name="FILE_NAME" /></translation>
@@ -921,6 +919,7 @@
 <translation id="2326606747676847821">Naviga in incognito</translation>
 <translation id="2326931316514688470">&amp;Ricarica app</translation>
 <translation id="2327492829706409234">Attiva applicazione</translation>
+<translation id="2329597144923131178">Accedi per visualizzare i tuoi Preferiti, la cronologia, le password e altre impostazioni su tutti i tuoi dispositivi.</translation>
 <translation id="2332131598580221120">Visualizza nello store</translation>
 <translation id="2332742915001411729">Ripristina impostazioni predefinite</translation>
 <translation id="2335122562899522968">Questa pagina ha impostato dei cookie.</translation>
@@ -944,7 +943,6 @@
 <translation id="2359808026110333948">Continua</translation>
 <translation id="236128817791440714">Consigliato: configura Smart Lock per Android</translation>
 <translation id="236141728043665931">Impedisci sempre l'accesso al microfono</translation>
-<translation id="2365626167708453863">Scegli un account da Google Smart Lock</translation>
 <translation id="2367972762794486313">Mostra app</translation>
 <translation id="2368075211218459617">Attiva ricerca contestuale.</translation>
 <translation id="2370882663124746154">Abilita modalità Double pinyin</translation>
@@ -2631,7 +2629,6 @@
 <translation id="4780374166989101364">Attiva le API sperimentali di estensione. Tieni presente che la galleria di estensione non consente tale utilizzo di API sperimentali.</translation>
 <translation id="4781787911582943401">Ingrandimento dello schermo</translation>
 <translation id="4782449893814226250">Hai chiesto ai tuoi genitori se puoi visitare questa pagina.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Presentazione PowerPoint</translation>
 <translation id="4785040501822872973">Il computer verrà reimpostato tra <ph name="LOGOUT_TIME_LEFT" /> secondi.
 Premi un tasto qualsiasi per continuare a esplorare.</translation>
@@ -3162,7 +3159,6 @@
 <translation id="5527474464531963247">Potresti inoltre selezionare un'altra rete.</translation>
 <translation id="5527963985407842218">Attivazione della Modalità Reader</translation>
 <translation id="5528368756083817449">Bookmark Manager</translation>
-<translation id="5529098031581368697">Lo sfondo attuale è stato impostato da "<ph name="APP_NAME" />"</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Generali</translation>
 <translation id="5533555070048896610">Traslitterazione (namaste → नमस्ते)</translation>
@@ -3278,7 +3274,6 @@
 <translation id="5702898740348134351">Modifica motori di ric&amp;erca...</translation>
 <translation id="5703594190584829406">Consente di visualizzare i suggerimenti di Compilazione automatica sopra la tastiera, anziché in un menu a discesa.</translation>
 <translation id="5704272569086782895">Attiva rasterizzazione GPU con thread.</translation>
-<translation id="570544101664452060">Notifiche WebUsb sperimentali.</translation>
 <translation id="5706551819490830015">Gestisci indirizzi di fatturazione...</translation>
 <translation id="5707185214361380026">Impossibile caricare l'estensione da:</translation>
 <translation id="5707604204219538797">Parola successiva</translation>
@@ -3427,7 +3422,6 @@
 <translation id="5900302528761731119">Foto profilo Google</translation>
 <translation id="5900623698597156974">Un fallback TLS 1.0 è riuscito a eseguire l'handshake con il server, ma i fallback TLS 1.0 non sono più accettati. Il server deve essere aggiornato per implementare correttamente la negoziazione della versione e supportare preferibilmente TLS 1.2.</translation>
 <translation id="590253956165195626">Consenti di tradurre pagine in lingue che non conosci.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 elemento}other{# elementi}}</translation>
 <translation id="5904093760909470684">Configurazione proxy</translation>
 <translation id="5906065664303289925">Indirizzo hardware:</translation>
 <translation id="5910363049092958439">Sal&amp;va immagine con nome...</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb
index dd36d77..074bbbf 100644
--- a/chrome/app/resources/generated_resources_iw.xtb
+++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">‏גש לכל אחד מהתקני ה-USB האלה</translation>
 <translation id="1038168778161626396">הצפן בלבד</translation>
 <translation id="1038842779957582377">שם לא ידוע</translation>
-<translation id="1040931876666128942">‏הודעות WebUsb.</translation>
 <translation id="1042174272890264476">‏המחשב שלך מגיע גם עם ספריית ה-RLZ המובנה של <ph name="SHORT_PRODUCT_NAME" />‏. RLZ מקצה תג שאינו ייחודי ואינו ניתן לזיהוי על מנת למדוד את החיפוש ואת השימוש ב-<ph name="SHORT_PRODUCT_NAME" /> המונעים על ידי קמפיין ספציפי לקידום מכירות. התוויות האלה מופיעות לעתים בשאילתות החיפוש של Google ב-<ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> רוצה לאחסן באופן קבוע כמות גדולה של נתונים במכשיר שלך.</translation>
 <translation id="1045157690796831147">‏תעתוק (namaskar → നമസ്കാരം)</translation>
@@ -327,7 +326,6 @@
 <translation id="1470719357688513792">‏הגדרות חדשות של קובצי Cookie ייכנסו לתוקף לאחר הטעינה מחדש של הדף.</translation>
 <translation id="14720830734893704">הפעל תמיכה במקלדת וירטואלית.</translation>
 <translation id="1474339897586437869">‏הקובץ "<ph name="FILENAME" />" לא הועלה. אין לך מספיק שטח פנוי ב-Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{סיסמה אחת}two{# סיסמאות}many{# סיסמאות}other{# סיסמאות}}</translation>
 <translation id="1476949146811612304">הגדר איזה מנוע חיפוש יופעל בעת חיפוש ב<ph name="BEGIN_LINK" />‏סרגל הכתובות<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">‏קובץ שמור של אסימון ממשק API של זהות</translation>
 <translation id="1478340334823509079">פרטים: <ph name="FILE_NAME" /></translation>
@@ -912,6 +910,7 @@
 <translation id="2326606747676847821">עבור למצב גלישה בסתר</translation>
 <translation id="2326931316514688470">&amp;טען אפליקציה מחדש</translation>
 <translation id="2327492829706409234">הפעל יישום</translation>
+<translation id="2329597144923131178">היכנס כדי לקבל גישה אל הסימניות, ההיסטוריה, הסיסמאות והגדרות נוספות בכל המכשירים שברשותך.</translation>
 <translation id="2332131598580221120">הצג בחנות</translation>
 <translation id="2332742915001411729">אפס לברירת המחדל</translation>
 <translation id="2335122562899522968">‏דף זה מגדיר קובצי Cookie.</translation>
@@ -935,7 +934,6 @@
 <translation id="2359808026110333948">המשך</translation>
 <translation id="236128817791440714">‏מומלץ: הגדר את Smart Lock ל-Android</translation>
 <translation id="236141728043665931">חסום תמיד גישה למיקרופון</translation>
-<translation id="2365626167708453863">‏בחר חשבון ממערכת Google Smart Lock</translation>
 <translation id="2367972762794486313">הצג יישומים</translation>
 <translation id="2368075211218459617">הפעל חיפוש קולי לפי הקשר</translation>
 <translation id="2370882663124746154">‏הפוך מצב Double-Pinyin לפעיל</translation>
@@ -2648,7 +2646,6 @@
 <translation id="4780374166989101364">‏מאפשרת ממשקי API ניסיוניים של תוספים. שים לב שגלריית התוספים לא מאפשרת לך לטעון תוספים שמשתמשים בממשקי API ניסיוניים.</translation>
 <translation id="4781787911582943401">התקרב לתצוגה</translation>
 <translation id="4782449893814226250">שאלת את הוריך אם זה בסדר לבקר בדף זה.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{‎1 kB}two{‎# kB}many{‎# kB}other{‎# kB}}</translation>
 <translation id="4784330909746505604">‏מצגת PowerPoint</translation>
 <translation id="4785040501822872973">מחשב זה יופעל מחדש בעוד <ph name="LOGOUT_TIME_LEFT" /> שניות.
 הקש על מקש כלשהו כדי להמשיך בסיור.</translation>
@@ -3179,7 +3176,6 @@
 <translation id="5527474464531963247">תוכל גם לבחור רשת אחרת.</translation>
 <translation id="5527963985407842218">הפעלת מצב קורא</translation>
 <translation id="5528368756083817449">מנהל הסימניות</translation>
-<translation id="5529098031581368697">הטפט הנוכחי נקבע על ידי '<ph name="APP_NAME" />'</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">גלובלי</translation>
 <translation id="5533555070048896610">‏תעתוק (namaste → नमस्ते)</translation>
@@ -3295,7 +3291,6 @@
 <translation id="5702898740348134351">&amp;ערוך מנועי חיפוש...</translation>
 <translation id="5703594190584829406">הצגת הצעות למילוי אוטומטי מעל למקלדת, במקום בתפריט נפתח.</translation>
 <translation id="5704272569086782895">‏הפעל עיבוד תוכן בשיטת Threaded GPU rasterization.</translation>
-<translation id="570544101664452060">‏הודעות WebUsb ניסיוניות.</translation>
 <translation id="5706551819490830015">ניהול כתובות לחיוב...</translation>
 <translation id="5707185214361380026">כשל בטעינת תוסף מ:</translation>
 <translation id="5707604204219538797">המילה הבאה</translation>
@@ -3442,7 +3437,6 @@
 <translation id="5900302528761731119">‏תמונת פרופיל Google</translation>
 <translation id="5900623698597156974">‏גיבוי מסוג TLS 1.0 הצליח לבצע לחיצת יד עם השרת, אך אנו כבר לא מקבלים גיבויי TLS 1.0. יש לעדכן את השרת כך שיטפל כראוי בסתירות בין גרסאות, עם עדיפות לתמיכה ב-TLS 1.2.</translation>
 <translation id="590253956165195626">הצע לתרגם דפים שאינם בשפה שאתה קורא.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{פריט אחד}two{# פריטים}many{# פריטים}other{# פריטים}}</translation>
 <translation id="5904093760909470684">‏תצורת שרת proxy</translation>
 <translation id="5906065664303289925">כתובת חומרה:</translation>
 <translation id="5910363049092958439">שמ&amp;ור תמונה כ...</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb
index a4efbcf..e60e9f9 100644
--- a/chrome/app/resources/generated_resources_ja.xtb
+++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">これらの USB デバイスへのアクセス</translation>
 <translation id="1038168778161626396">暗号化のみ</translation>
 <translation id="1038842779957582377">不明な名前</translation>
-<translation id="1040931876666128942">WebUsb の通知</translation>
 <translation id="1042174272890264476">お使いのパソコンには <ph name="SHORT_PRODUCT_NAME" /> の RLZ ライブラリも組み込まれています。RLZ は、個人を特定できないタグを割り当てて、特定の販促キャンペーンで生じた検索や <ph name="SHORT_PRODUCT_NAME" /> の利用状況を計測します。これらのラベルは <ph name="PRODUCT_NAME" /> で Google 検索キーワード内に表示されることがあります。</translation>
 <translation id="1042574203789536285"><ph name="URL" /> がこの端末に大量のデータを永続的に保存しようとしています。</translation>
 <translation id="1045157690796831147">文字変換(namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">新しい Cookie 設定はページの再読み込み後に有効になります。</translation>
 <translation id="14720830734893704">仮想キーボードのサポートを有効にします。</translation>
 <translation id="1474339897586437869">「<ph name="FILENAME" />」はアップロードされていません。Google ドライブに十分な空き容量がありません。</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 個のパスワード}other{# 個のパスワード}}</translation>
 <translation id="1476949146811612304">        <ph name="BEGIN_LINK" />アドレスバー<ph name="END_LINK" />
 から検索するときに使用する検索エンジンを設定します。</translation>
 <translation id="1477301030751268706">Identity API トークン キャッシュ</translation>
@@ -924,6 +922,7 @@
 <translation id="2326606747676847821">シークレット モード</translation>
 <translation id="2326931316514688470">アプリを再読み込み(&amp;R)</translation>
 <translation id="2327492829706409234">アプリを有効にする</translation>
+<translation id="2329597144923131178">ログインすると、お使いのどのデバイスでも同じブックマーク、履歴、パスワード、その他の設定を利用できるようになります。</translation>
 <translation id="2332131598580221120">ストアで見る</translation>
 <translation id="2332742915001411729">デフォルトに戻す</translation>
 <translation id="2335122562899522968">このページの Cookie が設定されました。</translation>
@@ -947,7 +946,6 @@
 <translation id="2359808026110333948">続行</translation>
 <translation id="236128817791440714">推奨: Smart Lock for Android を設定してください</translation>
 <translation id="236141728043665931">マイクのアクセスを常にブロックする</translation>
-<translation id="2365626167708453863">Google Smart Lock からアカウントを選択</translation>
 <translation id="2367972762794486313">アプリを表示</translation>
 <translation id="2368075211218459617">コンテキスト検索を有効にする</translation>
 <translation id="2370882663124746154">ダブルピンイン モードを有効にする</translation>
@@ -2657,7 +2655,6 @@
 <translation id="4780374166989101364">試験運用版の拡張機能 API を有効にします。試験運用版の API を使用した拡張機能は、拡張機能ギャラリーにはアップロードできませんのでご注意ください。</translation>
 <translation id="4781787911582943401">画面を拡大</translation>
 <translation id="4782449893814226250">このページを開いてもよいか保護者にたずねました。</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint プレゼンテーション</translation>
 <translation id="4785040501822872973">このパソコンは <ph name="LOGOUT_TIME_LEFT" /> 秒後にリセットされます。
 操作を続ける場合は、何かキーを押してください。</translation>
@@ -3188,7 +3185,6 @@
 <translation id="5527474464531963247">別のネットワークも選択できます。</translation>
 <translation id="5527963985407842218">リーダーモードの起動</translation>
 <translation id="5528368756083817449">ブックマーク マネージャ</translation>
-<translation id="5529098031581368697">現在の壁紙は「<ph name="APP_NAME" />」により設定されています</translation>
 <translation id="5531274207066050939">Google ペイメント</translation>
 <translation id="5532223876348815659">グローバル</translation>
 <translation id="5533555070048896610">文字変換(namaste → नमस्ते)</translation>
@@ -3304,7 +3300,6 @@
 <translation id="5702898740348134351">検索エンジンの編集(&amp;E)...</translation>
 <translation id="5703594190584829406">自動入力の候補をプルダウンではなくキーボードの上部に表示します。</translation>
 <translation id="5704272569086782895">スレッド GPU のラスター化を有効にする</translation>
-<translation id="570544101664452060">試験運用版の WebUsb 通知を有効にします。</translation>
 <translation id="5706551819490830015">請求先住所を管理...</translation>
 <translation id="5707185214361380026">次の場所から拡張機能を読み込むことができませんでした:</translation>
 <translation id="5707604204219538797">次の単語</translation>
@@ -3453,7 +3448,6 @@
 <translation id="5900302528761731119">Google プロフィール写真</translation>
 <translation id="5900623698597156974">TLS 1.0 フォールバックでサーバーとハンドシェイクすることができましたが、現在、TLS 1.0 フォールバックは承認されなくなりました。バージョン ネゴシエーションを正しく実装し、できれば TLS 1.2 をサポートするように、サーバーを更新する必要があります。</translation>
 <translation id="590253956165195626">母国語以外のページで翻訳ツールを表示する</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 個のアイテム}other{# 個のアイテム}}</translation>
 <translation id="5904093760909470684">プロキシ設定</translation>
 <translation id="5906065664303289925">ハードウェアのアドレス:</translation>
 <translation id="5910363049092958439">名前を付けて画像を保存(&amp;V)...</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb
index 61b4a2b..b066f03 100644
--- a/chrome/app/resources/generated_resources_kn.xtb
+++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">ಇವುಗಳಲ್ಲಿನ ಯಾವುದಾದರೂ USB ಸಾಧನಗಳನ್ನು ಪ್ರವೇಶಿಸಿ</translation>
 <translation id="1038168778161626396">ಸಂಕೇತಲಿಪಿ ಮಾತ್ರ</translation>
 <translation id="1038842779957582377">ಆಜ್ಞಾತ ಹೆಸರು</translation>
-<translation id="1040931876666128942">WebUsb ಅಧಿಸೂಚನೆಗಳು.</translation>
 <translation id="1042174272890264476">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಅಂತರ್‌ನಿರ್ಮಿತ <ph name="SHORT_PRODUCT_NAME" /> ನ RLZ ಲೈಬ್ರರಿಯೊಂದಿಗೆ ಸಹ ಬರುತ್ತದೆ. ಹುಡುಕಾಟಗಳನ್ನು ಅಳತೆ ಮಾಡಲು ಮತ್ತು ಒಂದು ನಿರ್ದಿಷ್ಟ ಪ್ರಚಾರದ ಶಿಬಿರದಿಂದ <ph name="SHORT_PRODUCT_NAME" /> ಬಳಕೆಯಿಂದ ಗಳಿಸಿದ ಅನನ್ಯವಲ್ಲದ, ವೈಯಕ್ತಿಕವಾಗಿ ಗುರುತಿಸದಂತಹ ಟ್ಯಾಗ್ ಅನ್ನು RLZ ಆಯೋಜಿಸುತ್ತದೆ. ಈ ಲೇಬಲ್‌ಗಳು ಕೆಲವು ಬಾರಿ <ph name="PRODUCT_NAME" /> ನಲ್ಲಿ Google ಹುಡುಕಾಟ ಪ್ರಶ್ನೆಗಳಲ್ಲಿ ಗೋಚರಿಸುತ್ತವೆ.</translation>
 <translation id="1042574203789536285">ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ದೊಡ್ಡ ಡೇಟಾವನ್ನು ಶಾಶ್ವತವಾಗಿ ಸಂಗ್ರಹಿಸಲು <ph name="URL" /> ಬಯಸುತ್ತದೆ.</translation>
 <translation id="1045157690796831147">ಲಿಪ್ಯಂತರಣ (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">ಪುಟವನ್ನು ಮರುಲೋಡ್ ಮಾಡಿದ ನಂತರ ಹೊಸ ಕುಕಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಕಾರ್ಯಗತವಾಗುತ್ತವೆ.</translation>
 <translation id="14720830734893704">ವರ್ಚುಯಲ್ ಕೀಬೋರ್ಡ್ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" ಅನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲಾಗಿಲ್ಲ. ನಿಮ್ಮ Google ಡ್ರೈವ್‌ನಲ್ಲಿ ಸಾಕಷ್ಟು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 ಪಾಸ್‌ವರ್ಡ್‌}one{# ಪಾಸ್‌ವರ್ಡ್‌ಗಳು}other{# ಪಾಸ್‌ವರ್ಡ್‌ಗಳು}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />ಓಮ್ನಿಬಾಕ್ಸ್<ph name="END_LINK" /> ಮೂಲಕ ಹುಡುಕಾಟ ನಡೆಸುತ್ತಿರುವಾಗ ಯಾವ ಹುಡುಕಾಟ ಎಂಜಿನ್ ಅನ್ನು ಬಳಸಬೇಕು ಎಂಬುದನ್ನು ಹೊಂದಿಸಿ.</translation>
 <translation id="1477301030751268706">ಗುರುತಿಸುವಿಕೆ API ಟೋಕನ್ ಕ್ಯಾಶ್</translation>
 <translation id="1478340334823509079">ವಿವರಗಳು: <ph name="FILE_NAME" /></translation>
@@ -930,6 +928,7 @@
 <translation id="2326606747676847821">ಅಜ್ಞಾತ ಬ್ರೌಸರ್‌ಗೆ ಹೋಗು</translation>
 <translation id="2326931316514688470">ಅಪ್ಲಿಕೇಶನ್ &amp;ಮರುಲೋಡ್ ಮಾಡಿ</translation>
 <translation id="2327492829706409234">ಅಪ್ಲಿಕೇಶನ್ ಸಕ್ರಿಯಗೊಳಿಸು</translation>
+<translation id="2329597144923131178">ನಿಮ್ಮ ಎಲ್ಲ ಸಾಧನಗಳಲ್ಲಿ ನಿಮ್ಮ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು, ಇತಿಹಾಸ ಮತ್ತು ಇತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಲು ಸೈನ್ ಇನ್ ಮಾಡಿ.</translation>
 <translation id="2332131598580221120">ಸ್ಟೋರ್‌ನಲ್ಲಿ ವೀಕ್ಷಿಸಿ</translation>
 <translation id="2332742915001411729">ಡೀಫಾಲ್ಟ್‌ಗೆ ಮರುಹೊಂದಿಸಿ</translation>
 <translation id="2335122562899522968">ಈ ಪುಟವು ಕುಕೀಸ್‌ಗಳನ್ನು ಸೆಟ್ ಮಾಡುತ್ತದೆ.</translation>
@@ -953,7 +952,6 @@
 <translation id="2359808026110333948">ಮುಂದುವರಿಸು</translation>
 <translation id="236128817791440714">ಶಿಫಾರಸು ಮಾಡಲಾಗಿದೆ: Android ಗಾಗಿ Smart Lock ಅನ್ನು ಹೊಂದಿಸಿ</translation>
 <translation id="236141728043665931">ಯಾವಾಗಲೂ ಮೈಕ್ರೋಫೋನ್ ಪ್ರವೇಶವನ್ನು ನಿರ್ಬಂಧಿಸಿ</translation>
-<translation id="2365626167708453863">ನಿಮ್ಮ Google Smart Lock ನಿಂದ ಖಾತೆಯನ್ನು ಆರಿಸಿ</translation>
 <translation id="2367972762794486313">ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ತೋರಿಸು</translation>
 <translation id="2368075211218459617">ಸಾಂದರ್ಭಿಕ ಹುಡಕಾಟವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ.</translation>
 <translation id="2370882663124746154">ಡಬಲ್-ಪಿನ್‌ಯಿನ್ ಮೋಡ್ ಅನ್ನು ಕ್ರಿಯಾತ್ಮಕಗೊಳಿಸಿ</translation>
@@ -2664,7 +2662,6 @@
 <translation id="4780374166989101364">ಪ್ರಾಯೋಗಿಕ ವಿಸ್ತರಣೆ APIಗಳನ್ನು ಸಕ್ರಿಯೆಗೊಳಿಸುತ್ತದೆ. ಪ್ರಾಯೋಗಿಕ APIಗಳನ್ನು ಬಳಸುವಂತಹ ವಿಸ್ತರಣೆಗಳನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲು ವಿಸ್ತರಣೆ ಗ್ಯಾಲರಿಯು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ ಎಂಬುದನ್ನು ಗಮನಿಸಿ.</translation>
 <translation id="4781787911582943401">ಪರದೆಯನ್ನು ಝೂಮ್ ಇನ್ ಮಾಡಿ</translation>
 <translation id="4782449893814226250">ಈ ಪುಟವನ್ನು ಭೇಟಿ ಮಾಡಬಹುದು ಎಂದು ನಿಮ್ಮ ಪೋಷಕರಿಗೆ ನೀವು ಕೇಳಿರುವಿರಿ.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}one{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint ಪ್ರದರ್ಶನ</translation>
 <translation id="4785040501822872973"><ph name="LOGOUT_TIME_LEFT" /> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಈ ಕಂಪ್ಯೂಟರ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ.
 ಅನ್ವೇಷಿಸುವುದನ್ನು ಮುಂದುವರಿಸಲು ಯಾವುದೇ ಕೀ ಅನ್ನು ಒತ್ತಿರಿ.</translation>
@@ -3198,7 +3195,6 @@
 <translation id="5527474464531963247">ನೀವು ಇನ್ನೊಂದು ನೆಟ್‌‌ವರ್ಟ್ ಅನ್ನು ಸಹ ಆಯ್ಕೆಮಾಡಿಕೊಳ್ಳಬಹುದು.</translation>
 <translation id="5527963985407842218">ರೀಡರ್ ಮೋಡ್ ಟ್ರಿಗರಿಂಗ್</translation>
 <translation id="5528368756083817449">ಬುಕ್‌ಮಾರ್ಕ್‌ ವ್ಯವಸ್ಥಾಪಕ</translation>
-<translation id="5529098031581368697">ಪ್ರಸ್ತುತ ವಾಲ್‌ಪೇಪರ್ ಅನ್ನು '<ph name="APP_NAME" />' ರಿಂದ ಹೊಂದಿಸಲಾಗಿದೆ</translation>
 <translation id="5531274207066050939">Google ಪಾವತಿಗಳು</translation>
 <translation id="5532223876348815659">ಜಾಗತಿಕ</translation>
 <translation id="5533555070048896610">ಲಿಪ್ಯಂತರಣ (namaste → नमस्ते)</translation>
@@ -3314,7 +3310,6 @@
 <translation id="5702898740348134351">ಹುಡುಕಾಟ ಎಂಜಿನ್ ಅನ್ನು &amp;ಸಂಪಾದಿಸಿ...</translation>
 <translation id="5703594190584829406">ಸ್ವಯಂ ಭರ್ತಿ ಸಲಹೆಗಳನ್ನು ಡ್ರಾಪ್‌ಡೌನ್ ಬದಲಿಗೆ ಕೀಬೋರ್ಡ್‌ನ ಮೇಲ್ಭಾಗದಲ್ಲಿ ತೋರಿಸುತ್ತದೆ.</translation>
 <translation id="5704272569086782895">ಥ್ರೆಡ್ ಮಾಡಲಾದ GPU ರಾಸ್ಟರೈಸೇಶನ್ ಸಕ್ರಿಯಗೊಳಿಸಿ.</translation>
-<translation id="570544101664452060">ಪ್ರಾಯೋಗಿಕ WebUsb ಅಧಿಸೂಚನೆಗಳು.</translation>
 <translation id="5706551819490830015">ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸಗಳನ್ನು ನಿರ್ವಹಿಸಿ...</translation>
 <translation id="5707185214361380026">ಇದರಿಂದ ವಿಸ್ತರಣೆಯನ್ನು ಲೋಡ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ:</translation>
 <translation id="5707604204219538797">ಮುಂದಿನ ಪದ</translation>
@@ -3463,7 +3458,6 @@
 <translation id="5900302528761731119">Google ಪ್ರೊಫೈಲ್ ಫೋಟೋ</translation>
 <translation id="5900623698597156974">A TLS 1.0 ಹಿಂತಿರುಗಿಸುವಿಕೆಗೆ ಸರ್ವರ್‌ ಜೊತೆಗೆ ಹ್ಯಾಂಡ್‌ಶೇಕ್‌ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ, ಆದರೆ ನಾವು ಇನ್ನು ಮುಂದೆ TLS 1.0 ಹಿಂತಿರುಗಿಸುವಿಕೆಗಳನ್ನು ಸಮ್ಮತಿಸುವುದಿಲ್ಲ. ಸರ್ವರ್‌ಗೆ ಸರಿಯಾಗಿ ಕಾರ್ಯಗತಗೊಳಿಸುವ ಆವೃತ್ತಿಗೆ ಅಪ್‌ಡೇಟ್ ಮಾಡುವ ಮತ್ತು TLS 1.2 ಗೆ ಬೆಂಬಲಿಸುವ ಅಗತ್ಯವಿದೆ.</translation>
 <translation id="590253956165195626">ನನ್ನ ಭಾಷೆಯಲ್ಲಿಲ್ಲದ ಪುಟಗಳನ್ನು ಅನುವಾದ ಮಾಡುವ ಆಫರ್‌‌ ನೀಡು.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 ಐಟಂ}one{# ಐಟಂಗಳು}other{# ಐಟಂಗಳು}}</translation>
 <translation id="5904093760909470684">ಪ್ರಾಕ್ಸಿ ಕಾನ್ಫಿಗರೇಶನ್</translation>
 <translation id="5906065664303289925">ಹಾರ್ಡ್‌ವೇರ್  ವಿಳಾಸ:</translation>
 <translation id="5910363049092958439">ಇದರಂತೆ ಇಮೇಜ್ ಉ&amp;ಳಿಸಿ...</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb
index 5612ad4..f760b6c 100644
--- a/chrome/app/resources/generated_resources_ko.xtb
+++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">이 USB 기기에 액세스</translation>
 <translation id="1038168778161626396">암호화만</translation>
 <translation id="1038842779957582377">알 수 없는 이름</translation>
-<translation id="1040931876666128942">WebUsb 알림</translation>
 <translation id="1042174272890264476">또한 컴퓨터에는 <ph name="SHORT_PRODUCT_NAME" /> RLZ 라이브러리가 내장되어 있습니다. RLZ는 고유하지 않고 개인 식별이 불가능한 태그를 할당하여 특정 홍보 캠페인을 통한 검색 및 <ph name="SHORT_PRODUCT_NAME" /> 사용 실태를 측정합니다. 이러한 라벨은 <ph name="PRODUCT_NAME" />의 Google 검색어에 표시되기도 합니다.</translation>
 <translation id="1042574203789536285"><ph name="URL" />에서 내 기기에 대용량 데이터를 영구적으로 저장하려고 합니다.</translation>
 <translation id="1045157690796831147">음역(namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">새 쿠키 설정은 페이지를 새로고침한 다음에 적용됩니다.</translation>
 <translation id="14720830734893704">가상 키보드 지원을 사용합니다.</translation>
 <translation id="1474339897586437869">'<ph name="FILENAME" />'이(가) 업로드되지 않았습니다. Google 드라이브에 충분한 여유 공간이 없습니다.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{비밀번호 1개}other{비밀번호 #개}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />검색주소창<ph name="END_LINK" />에서 검색할 때 사용할 검색엔진을
         설정합니다.</translation>
 <translation id="1477301030751268706">Identity API 토큰 캐시</translation>
@@ -925,6 +923,7 @@
 <translation id="2326606747676847821">시크릿 탭 열기</translation>
 <translation id="2326931316514688470">앱 새로고침(&amp;R)</translation>
 <translation id="2327492829706409234">앱 사용</translation>
+<translation id="2329597144923131178">로그인하면 모든 기기에서 북마크, 방문 기록, 비밀번호, 기타 설정을 사용할 수 있습니다.</translation>
 <translation id="2332131598580221120">스토어에서 보기</translation>
 <translation id="2332742915001411729">기본 설정으로 돌아가기</translation>
 <translation id="2335122562899522968">이 페이지에서 쿠키를 설정합니다.</translation>
@@ -948,7 +947,6 @@
 <translation id="2359808026110333948">계속</translation>
 <translation id="236128817791440714">추천: Android용 Smart Lock 설정</translation>
 <translation id="236141728043665931">마이크 액세스 항상 차단</translation>
-<translation id="2365626167708453863">Google Smart Lock에서 계정 선택</translation>
 <translation id="2367972762794486313">앱 표시</translation>
 <translation id="2368075211218459617">문맥 검색을 사용합니다.</translation>
 <translation id="2370882663124746154">이중 병음 모드 사용</translation>
@@ -2667,7 +2665,6 @@
 <translation id="4780374166989101364">실험실 확장 프로그램 API를 사용합니다. 확장 프로그램 갤러리에서는 실험실 API를 사용하는 확장 프로그램을 업로드할 수 없습니다.</translation>
 <translation id="4781787911582943401">화면 확대</translation>
 <translation id="4782449893814226250">이 페이지를 방문해도 괜찮은지 부모님께 문의했습니다.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1kB}other{#kB}}</translation>
 <translation id="4784330909746505604">PowerPoint 프레젠테이션</translation>
 <translation id="4785040501822872973">이 컴퓨터는 <ph name="LOGOUT_TIME_LEFT" />초 후에 재설정됩니다.
 계속하려면 아무 키나 누르세요.</translation>
@@ -3198,7 +3195,6 @@
 <translation id="5527474464531963247">다른 네트워크를 선택할 수도 있습니다.</translation>
 <translation id="5527963985407842218">리더 모드 실행 중</translation>
 <translation id="5528368756083817449">북마크 관리자</translation>
-<translation id="5529098031581368697">현재 배경화면은 '<ph name="APP_NAME" />'에서 설정했습니다.</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">전체</translation>
 <translation id="5533555070048896610">음역(namaste → नमस्ते)</translation>
@@ -3314,7 +3310,6 @@
 <translation id="5702898740348134351">검색 엔진 변경(&amp;E)...</translation>
 <translation id="5703594190584829406">드롭다운이 아니라 키보드 상단에 자동완성 제안을 표시합니다.</translation>
 <translation id="5704272569086782895">스레드된 GPU 래스터화를 사용합니다.</translation>
-<translation id="570544101664452060">실험용 WebUsb 알림</translation>
 <translation id="5706551819490830015">청구지 주소 관리</translation>
 <translation id="5707185214361380026">다음 위치에서 확장 프로그램을 로드하지 못했습니다.</translation>
 <translation id="5707604204219538797">다음 글자</translation>
@@ -3463,7 +3458,6 @@
 <translation id="5900302528761731119">Google 프로필 사진</translation>
 <translation id="5900623698597156974">TLS 1.0 대체에서 서버와 연결할 수 있었지만 Google에서는 더 이상 TLS 1.0 대체를 허용하지 않습니다. 서버가 제대로 버전 협상을 구현하고 TLS 1.2를 지원하도록 업데이트되어야 합니다.</translation>
 <translation id="590253956165195626">사용 언어가 다른 페이지에 대한 번역 옵션 제공</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{항목 1개}other{항목 #개}}</translation>
 <translation id="5904093760909470684">프록시 설정</translation>
 <translation id="5906065664303289925">하드웨어 주소:</translation>
 <translation id="5910363049092958439">이미지를 다른 이름으로 저장(&amp;V)...</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb
index 7cde402e..c88b84f 100644
--- a/chrome/app/resources/generated_resources_lt.xtb
+++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Pasiekti bet kurį iš šių USB įrenginių</translation>
 <translation id="1038168778161626396">Tik šifruoti</translation>
 <translation id="1038842779957582377">nežinomas pavadinimas</translation>
-<translation id="1040931876666128942">„WebUsb“ pranešimai.</translation>
 <translation id="1042174272890264476">Jūsų kompiuteryje taip pat įdiegta „<ph name="SHORT_PRODUCT_NAME" />“ RLZ biblioteka. RLZ priskiria neunikalią, asmens neidentifikuojančią žymą, kad įvertintų tam tikros reklamos kampanijos paieškas ir „<ph name="SHORT_PRODUCT_NAME" />“ naudojimą. Šios etiketės kartais rodomos „Google“ paieškos užklausose „<ph name="PRODUCT_NAME" />“.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> pageidaujama visam laikui išsaugoti daug duomenų įrenginyje.</translation>
 <translation id="1045157690796831147">Transliteracija (namaskar → നമസ്കാരം)</translation>
@@ -330,7 +329,6 @@
 <translation id="1470719357688513792">Nauji slapukų nustatymai pradės galioti iš naujo įkėlus puslapį.</translation>
 <translation id="14720830734893704">Įgalinamas virtualiosios klaviatūros palaikymas.</translation>
 <translation id="1474339897586437869">Failas „<ph name="FILENAME" />“ neįkeltas. „Google“ diske nepakanka vietos.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 slaptažodis}one{# slaptažodis}few{# slaptažodžiai}many{# slaptažodžio}other{# slaptažodžių}}</translation>
 <translation id="1476949146811612304">Nustatyti, kuris paieškos variklis naudojamas ieškant <ph name="BEGIN_LINK" />„Omnibox“<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Tapatybės API prieigos rakto talpykla</translation>
 <translation id="1478340334823509079">Išsami informacija: „<ph name="FILE_NAME" />“</translation>
@@ -928,6 +926,7 @@
 <translation id="2326606747676847821">Įjungti inkognito režimą</translation>
 <translation id="2326931316514688470">&amp;Įkelti programą iš naujo</translation>
 <translation id="2327492829706409234">Įgalinti programą</translation>
+<translation id="2329597144923131178">Pris. ir pas. žymių, ist., slapt. bei kitų nust. duom. visuose įreng.</translation>
 <translation id="2332131598580221120">Žiūrėti parduotuvėje</translation>
 <translation id="2332742915001411729">Nustatyti iš naujo numatytąjį</translation>
 <translation id="2335122562899522968">Šis puslapis nustatė slapukus.</translation>
@@ -951,7 +950,6 @@
 <translation id="2359808026110333948">Tęsti</translation>
 <translation id="236128817791440714">Rekomenduojama: nustatykite „Smart Lock“, skirtą „Android“</translation>
 <translation id="236141728043665931">Visada blokuoti prieigą prie mikrofono</translation>
-<translation id="2365626167708453863">Pasirinkite paskyrą iš „Google Smart Lock“</translation>
 <translation id="2367972762794486313">Rodyti programas</translation>
 <translation id="2368075211218459617">Įgalinti Kontekstinę paiešką</translation>
 <translation id="2370882663124746154">Įgalinti dvigubą Pinjino režimą</translation>
@@ -1056,7 +1054,7 @@
         Kad negeneruotumėte per daug srauto ir nepablogintumėte situacijos,
         užklausos šiuo URL laikinai neleidžiamos.</translation>
 <translation id="2505402373176859469"><ph name="RECEIVED_AMOUNT" /> iš <ph name="TOTAL_SIZE" /></translation>
-<translation id="2507649982651274960">Įrenginys sėkmingai užregistruotas įmonei valdyti, tačiau nepavyko išsiųsti jo išteklių ir vietos informacijos. Rankiniu būdu įveskite šią informaciją įrenginio administratoriaus pulte.</translation>
+<translation id="2507649982651274960">Įrenginys sėkmingai užregistruotas įmonei valdyti, tačiau nepavyko išsiųsti jo išteklių ir vietos informacijos. Įveskite šią informaciją neautomatiškai įrenginio administratoriaus pulte.</translation>
 <translation id="2508404591020172552"><ph name="DOWNLOAD_RECEIVED_AND_TOTAL" /> iš <ph name="DOWNLOAD_DOMAIN" /></translation>
 <translation id="2509739495444557741">Neįdiegta jokių papildinių.</translation>
 <translation id="2509857212037838238">Įdiegti „<ph name="PLUGIN_NAME" />“</translation>
@@ -2667,7 +2665,6 @@
 <translation id="4780374166989101364">Įgalinamos bandomųjų plėtinių API. Atminkite, kad į plėtinių galeriją neleidžiama įkelti plėtinių, kuriems naudojamos bandomosios API.</translation>
 <translation id="4781787911582943401">Artinti ekraną</translation>
 <translation id="4782449893814226250">Paprašėte tėvų leidimo apsilankyti šiame puslapyje.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}one{# KB}few{# KB}many{# KB}other{# KB}}</translation>
 <translation id="4784330909746505604">„PowerPoint“ pristatymas</translation>
 <translation id="4785040501822872973">Šis kompiuteris bus nustatytas iš naujo po <ph name="LOGOUT_TIME_LEFT" /> sek.
 Jei norite toliau naršyti, paspauskite bet kurį klavišą.</translation>
@@ -2882,7 +2879,7 @@
 <translation id="5109044022078737958">Austra</translation>
 <translation id="5111692334209731439">&amp;Žymių tvarkytuvė</translation>
 <translation id="5112577000029535889">&amp;Kūrėjo įrankiai</translation>
-<translation id="5113739826273394829">Spustelėję šią piktogramą, rankiniu būdu užrakinsite šį „<ph name="DEVICE_TYPE" />“. Kitą kartą norėdami įeiti turėsite įvesti slaptažodį.</translation>
+<translation id="5113739826273394829">Spustelėję šią piktogramą, neautomatiškai užrakinsite šį „<ph name="DEVICE_TYPE" />“. Kitą kartą norėdami įeiti turėsite įvesti slaptažodį.</translation>
 <translation id="5116300307302421503">Nepavyksta išanalizuoti failo.</translation>
 <translation id="5116628073786783676">Iš&amp;saugoti garso įrašą kaip...</translation>
 <translation id="5117930984404104619">Stebėti kitų plėtinių veikimą, įskaitant aplankytus URL</translation>
@@ -3198,7 +3195,6 @@
 <translation id="5527474464531963247">Be to, galite pasirinkti kitą tinklą.</translation>
 <translation id="5527963985407842218">Skaitymo režimo suaktyvinimas</translation>
 <translation id="5528368756083817449">Žymių tvarkytuvė</translation>
-<translation id="5529098031581368697">Dabartinį ekrano foną nustatė „<ph name="APP_NAME" />“</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Visuotinės</translation>
 <translation id="5533555070048896610">Transliteracija (namaste → नमस्ते)</translation>
@@ -3315,7 +3311,6 @@
 <translation id="5702898740348134351">&amp;Redaguoti paieškos variklius...</translation>
 <translation id="5703594190584829406">Automatinio pildymo pasiūlymai rodomi klaviatūros viršuje, o ne išskleidžiamajame meniu.</translation>
 <translation id="5704272569086782895">Įgalinti grupės GPU rastrinio vaizdo keitimą.</translation>
-<translation id="570544101664452060">Eksperimentiniai „WebUsb“ pranešimai.</translation>
 <translation id="5706551819490830015">Valdyti atsiskaitymo adresus…</translation>
 <translation id="5707185214361380026">Nepavyko įkelti plėtinio iš:</translation>
 <translation id="5707604204219538797">Kitas žodis</translation>
@@ -3465,7 +3460,6 @@
 <translation id="5900302528761731119">„Google“ profilio nuotrauka</translation>
 <translation id="5900623698597156974">1.0 versijos TLS surogatui pavyko užmegzti ryšį su serveriu, bet mes nebepriimame 1.0 versijos TLS surogatų. Reikia atnaujinti serverį, kad būtų tinkamai pritaikytas versijos derinimas ir, pageidautina, 1.2 versijos TLS palaikymas.</translation>
 <translation id="590253956165195626">Siūlyti versti puslapius, kurie pateikiami ne skaitoma kalba.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 elementas}one{# elementas}few{# elementai}many{# elemento}other{# elementų}}</translation>
 <translation id="5904093760909470684">Tarpinio serverio konfigūracija</translation>
 <translation id="5906065664303289925">Aparatinės įrangos adresas:</translation>
 <translation id="5910363049092958439">Iš&amp;saugoti vaizdą kaip...</translation>
@@ -4741,7 +4735,7 @@
 <translation id="7805768142964895445">Būsena</translation>
 <translation id="7806513705704909664">Įgalinti automatinį pildymą, kad būtų galima užpildyti žiniatinklio formas vienu paspaudimu.</translation>
 <translation id="7807711621188256451">Visada leisti <ph name="HOST" /> pasiekti fotoaparatą</translation>
-<translation id="7809868303668093729">Eksperimentinis slinkimo pabaigos efektas, atsakant į vertikalų slinkimą aukštyn.</translation>
+<translation id="7809868303668093729">Eksperimentinis slinkimo pabaigos efektas, atsakant į vertikaliąją slinktį aukštyn.</translation>
 <translation id="7810202088502699111">Šiame puslapyje iššokantieji langai buvo užblokuoti.</translation>
 <translation id="7812634759091149319">Nustatoma, kad įrankių komplekto rodiniais pagrįstą programos informacijos dialogo langą būtų galima pasiekti adresu chrome://apps ar chrome://extensions vietoje vietinio plėtinio leidimų dialogo lango ar išsamios informacijos nuorodos (kuri yra nuoroda į internetinę parduotuvę).</translation>
 <translation id="7814458197256864873">&amp;Kopijuoti</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb
index 86455c6..3246007 100644
--- a/chrome/app/resources/generated_resources_lv.xtb
+++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Piekļūt jebkurai no šīm USB ierīcēm</translation>
 <translation id="1038168778161626396">Tikai šifrēt</translation>
 <translation id="1038842779957582377">nezināms nosaukums</translation>
-<translation id="1040931876666128942">WebUsb paziņojumi</translation>
 <translation id="1042174272890264476">Jūsu datorā ir iebūvēta arī pārlūka <ph name="SHORT_PRODUCT_NAME" /> RLZ bibliotēka. RLZ piešķir neunikālu, personu neidentificējošu atzīmi, lai novērtētu noteiktas reklāmas kampaņas ietvaros ievadītos meklēšanas vienumus un pārlūka <ph name="SHORT_PRODUCT_NAME" /> lietojumu. Šīs atzīmes pārlūkā <ph name="PRODUCT_NAME" /> dažkārt tiek rādītas Google meklēšanas vaicājumos.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> vēlas jūsu ierīcē neatgriezeniski glabāt lielu datu apjomu.</translation>
 <translation id="1045157690796831147">Transliterācija (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Jaunie sīkfailu iestatījumi stāsies spēkā pēc šīs lapas atkārtotas ielādes.</translation>
 <translation id="14720830734893704">Iespējo virtuālās tastatūras atbalstu.</translation>
 <translation id="1474339897586437869">Fails “<ph name="FILENAME" />” netika augšupielādēts. Jūsu Google diskā nepietiek vietas.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 parole}zero{# paroļu}one{# parole}other{# paroles}}</translation>
 <translation id="1476949146811612304">Iestatīt, kura meklētājprogramma tiek izmantota, kad tiek meklēts no <ph name="BEGIN_LINK" />universālā lodziņa<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Identifikācijas datu API pilnvaru kešatmiņa</translation>
 <translation id="1478340334823509079">Detalizēta informācija: <ph name="FILE_NAME" /></translation>
@@ -923,6 +921,7 @@
 <translation id="2326606747676847821">Pārlūkojiet inkognito režīmā</translation>
 <translation id="2326931316514688470">&amp;Atkārtoti ielādēt lietotni</translation>
 <translation id="2327492829706409234">Iespējot lietotni</translation>
+<translation id="2329597144923131178">Pierakstieties, lai grāmatzīmes, vēsture, paroles u.c. būtu pieejamas visās jūsu ierīcēs.</translation>
 <translation id="2332131598580221120">Skatīt veikalā</translation>
 <translation id="2332742915001411729">Atiestatīt noklusējuma iestatījumus</translation>
 <translation id="2335122562899522968">Šī lapa iestatīja sīkfailus.</translation>
@@ -946,7 +945,6 @@
 <translation id="2359808026110333948">Turpināt</translation>
 <translation id="236128817791440714">Ieteicams iestatīt sistēmu Smart Lock Android ierīcēm</translation>
 <translation id="236141728043665931">Vienmēr bloķēt piekļuvi mikrofonam</translation>
-<translation id="2365626167708453863">Izvēlieties kontu no savas sistēmas Google Smart Lock</translation>
 <translation id="2367972762794486313">Rādīt lietotnes</translation>
 <translation id="2368075211218459617">Iespējot kontekstuālo meklēšanu</translation>
 <translation id="2370882663124746154">Iespējot Double-Pinyin režīmu</translation>
@@ -2664,7 +2662,6 @@
 <translation id="4780374166989101364">Iespējo eksperimentālo paplašinājumu API. Ņemiet vērā, ka paplašinājumu galerija neļauj augšupielādēt paplašinājumus, kas izmanto eksperimentālos API.</translation>
 <translation id="4781787911582943401">Tuvināt ekrānu</translation>
 <translation id="4782449893814226250">Jūs lūdzāt vecākiem atļauju apmeklēt šo lapu.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}zero{# kB}one{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint prezentācija</translation>
 <translation id="4785040501822872973">Šis dators tiks atiestatīts pēc <ph name="LOGOUT_TIME_LEFT" /> sekundes(-ēm).
 Lai turpinātu skatīšanu, nospiediet jebkuru taustiņu.</translation>
@@ -3195,7 +3192,6 @@
 <translation id="5527474464531963247">Varat arī atlasīt citu tīklu.</translation>
 <translation id="5527963985407842218">Lasīšanas režīma aktivizēšana</translation>
 <translation id="5528368756083817449">Grāmatzīmju pārvaldnieks</translation>
-<translation id="5529098031581368697">Pašreizējo fona tapeti iestatīja <ph name="APP_NAME" /></translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Visā pasaulē</translation>
 <translation id="5533555070048896610">Transliterācija (namaste → नमस्ते)</translation>
@@ -3311,7 +3307,6 @@
 <translation id="5702898740348134351">R&amp;ediģēt meklētājprogrammas...</translation>
 <translation id="5703594190584829406">Rāda automātiskās aizpildes ieteikumus virs tastatūras, nevis nolaižamajā izvēlnē.</translation>
 <translation id="5704272569086782895">Iespējot pavedienu GPU rastrēšanu.</translation>
-<translation id="570544101664452060">Eksperimentāli WebUsb paziņojumi</translation>
 <translation id="5706551819490830015">Pārvaldīt norēķinu adreses...</translation>
 <translation id="5707185214361380026">Neizdevās ielādēt paplašinājumu no:</translation>
 <translation id="5707604204219538797">Nākamais vārds</translation>
@@ -3460,7 +3455,6 @@
 <translation id="5900302528761731119">Google profila fotoattēls</translation>
 <translation id="5900623698597156974">Izmantojot TLS 1.0 atkāpšanās protokolu, izdevās izveidot savienojumu ar serveri, taču TLS 1.0 atkāpšanās protokoli vairs netiek pieņemti. Lai pareizi veiktu versiju saskaņošanu, serveris ir jāatjaunina (ieteicams nodrošināt protokola TLS versijas 1.2 atbalstu).</translation>
 <translation id="590253956165195626">Piedāvāt tulkot lapas, kas nav manā valodā</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 vienums}zero{# vienumu}one{# vienums}other{# vienumi}}</translation>
 <translation id="5904093760909470684">Starpniekservera konfigurācija</translation>
 <translation id="5906065664303289925">Aparatūras adrese:</translation>
 <translation id="5910363049092958439">Saglabāt attēlu &amp;kā...</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb
index 4028f71..0e36d934 100644
--- a/chrome/app/resources/generated_resources_ml.xtb
+++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">ഈ USB ഉപകരണങ്ങളിലേതിലേക്കെങ്കിലും ആക്സസ്സുചെയ്യുക</translation>
 <translation id="1038168778161626396">എന്‍‌സിഫര്‍‌ മാത്രം</translation>
 <translation id="1038842779957582377">അജ്ഞാത നാമം</translation>
-<translation id="1040931876666128942">WebUsb അറിയിപ്പുകൾ.</translation>
 <translation id="1042174272890264476">നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ <ph name="SHORT_PRODUCT_NAME" /> എന്നതിന്റെ RLZ ലൈബ്രറി അന്തർനിർമ്മിതവുമാണ്. RLZ, ഒരു നിർദ്ദിഷ്‌ട പ്രമോഷണൽ കാമ്പെയ്‌നിലൂടെ ലഭിക്കുന്ന തിരയലുകളും <ph name="SHORT_PRODUCT_NAME" /> ഉപയോഗവും കണക്കാക്കുന്നതിന് അദ്വിതീയമല്ലാത്തതും വ്യക്തിപരമായി തിരിച്ചറിയാനാകാത്തതുമായ ഒരു ടാഗ് നിയുക്തമാക്കുന്നു. ഈ ലേബലുകൾ ചിലസമയത്ത് <ph name="PRODUCT_NAME" /> എന്നതിലെ Google തിരയലിൽ ദൃശ്യമാകുന്നു.</translation>
 <translation id="1042574203789536285"><ph name="URL" />, നിങ്ങളുടെ ഉപകരണത്തിൽ ശാശ്വതമായി വലിയ അളവിൽ ഡാറ്റ സംഭരിക്കാന്‍ താൽപ്പര്യപ്പെടുന്നു.</translation>
 <translation id="1045157690796831147">ലിപ്യന്തരണം (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">പേജ് റീലോഡ് ചെയ്തതിനുശേഷം പുതിയ കുക്കി ക്രമീകരണങ്ങള്‍ പ്രാബല്യത്തില്‍ വരും.</translation>
 <translation id="14720830734893704">വെർച്വൽ കീബോർഡ് പിന്തുണ പ്രവർത്തനക്ഷമമാക്കുക.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" അപ്‌ലോഡുചെയ്‌തില്ല. നിങ്ങളുടെ Google ഡ്രൈവിൽ മതിയായ ഇടമില്ല.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{ഒരു പാസ്‌വേഡ്}other{# പാസ്‌വേഡുകൾ}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />ഓമ്‌നിബോക്‌സിൽ<ph name="END_LINK" />
         നിന്ന് തിരയുമ്പോൾ ഏത് തിരയൽ എഞ്ചിനാണ് ഉപയോഗിക്കുന്നതെന്ന് സജ്ജമാക്കുക.</translation>
 <translation id="1477301030751268706">ഐഡന്റിറ്റി API ടോക്കൺ കാഷെ</translation>
@@ -928,6 +926,7 @@
 <translation id="2326606747676847821">ആൾമാറാട്ടത്തിലേക്ക് പോകുക</translation>
 <translation id="2326931316514688470">അപ്ലിക്കേഷൻ &amp;വീണ്ടും ലോഡുചെയ്യുക</translation>
 <translation id="2327492829706409234">അപ്ലിക്കേഷനുകൾ പ്രാപ്‌തമാക്കുക</translation>
+<translation id="2329597144923131178">നിങ്ങളുടെ എല്ലാ ഉപകരണങ്ങളിലും ബുക്ക്‌മാർക്കുകളും ചരിത്രവും മറ്റ് ക്രമീകരണവും ലഭിക്കാൻ സൈൻ ഇൻ ചെയ്യുക.</translation>
 <translation id="2332131598580221120">സ്റ്റോറിൽ കാണുക</translation>
 <translation id="2332742915001411729">സ്ഥിരസ്ഥിതിയിലേക്ക് പുനഃസജ്ജമാക്കുക</translation>
 <translation id="2335122562899522968">ഈ പേജ് കുക്കികളെ സജ്ജമാക്കുന്നു.</translation>
@@ -951,7 +950,6 @@
 <translation id="2359808026110333948">തുടരൂ</translation>
 <translation id="236128817791440714">ശുപാർശ ചെയ്യുന്നത്: Android-നുള്ള Smart Lock സജ്ജീകരിക്കുക</translation>
 <translation id="236141728043665931">എല്ലായ്‌പ്പോഴും മൈക്രോഫോൺ ആക്‌സസ്സ് തടയുക</translation>
-<translation id="2365626167708453863">നിങ്ങളുടെ Google Smart Lock-ൽ നിന്ന് ഒരു അക്കൗണ്ട് തിരഞ്ഞെടുക്കുക</translation>
 <translation id="2367972762794486313">അപ്ലിക്കേഷനുകൾ കാണിക്കുക</translation>
 <translation id="2368075211218459617">സാന്ദർഭിക തിരയൽ പ്രവർത്തനക്ഷമമാക്കുക.</translation>
 <translation id="2370882663124746154">ഇരട്ട-പിന്‍‌യിന്‍‌ മോഡ് പ്രാപ്‌തമാക്കുക</translation>
@@ -2671,7 +2669,6 @@
 <translation id="4780374166989101364">പരീക്ഷണ വിപുലീകരണ APIകള്‍ പ്രാപ്തമാക്കുന്നു.  വിപുലീകരണ ഗാലറി പരീക്ഷണ API കള്‍ ഉപയോഗിക്കുന്ന വിപുലീകരണങ്ങള്‍ അപ്‌ലോഡ് ചെയ്യാന്‍ അനുവദിക്കില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക.</translation>
 <translation id="4781787911582943401">സ്‌ക്രീൻ സൂം ഇൻ ചെയ്യുക</translation>
 <translation id="4782449893814226250">നിങ്ങളുടെ രക്ഷിതാക്കളോട് ചോദിച്ച് അനുവാദം ലഭിക്കുകയാണെങ്കിൽ ഈ പേജ് സന്ദർശിക്കുക.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint അവതരണം</translation>
 <translation id="4785040501822872973">ഈ കമ്പ്യൂട്ടർ <ph name="LOGOUT_TIME_LEFT" /> സെക്കൻഡിനുള്ളിൽ പുനഃസജ്ജമാക്കും.
 പര്യവേക്ഷണം തുടരുന്നതിനായി ഏതെങ്കിലും കീ അമർത്തുക.</translation>
@@ -3202,7 +3199,6 @@
 <translation id="5527474464531963247">നിങ്ങൾക്ക് മറ്റൊരു നെറ്റ്‌വർക്കും തിരഞ്ഞെടുക്കാവുന്നതാണ്.</translation>
 <translation id="5527963985407842218">റീഡർ മോഡ് ട്രിഗ്ഗർ ചെയ്യൽ</translation>
 <translation id="5528368756083817449">ബുക്മാര്‍ക്ക് മാനേജര്‍</translation>
-<translation id="5529098031581368697">'<ph name="APP_NAME" />' ആണ് നിലവിലെ വാൾപേപ്പർ സജ്ജീകരിച്ചത്</translation>
 <translation id="5531274207066050939">Google പേയ്മെന്റ്</translation>
 <translation id="5532223876348815659">ആഗോളം</translation>
 <translation id="5533555070048896610">ലിപ്യന്തരണം (namaste → नमस्ते)</translation>
@@ -3316,7 +3312,6 @@
 <translation id="5702898740348134351">&amp;തിരയല്‍‌ എഞ്ചിനുകള്‍‌ എഡിറ്റുചെയ്യുക...</translation>
 <translation id="5703594190584829406">ഒരു ഡ്രോപ്പ്ഡൗണിന് പകരം കീബോർഡിനുമുകളിൽ ഓട്ടോഫിൽ നിർദ്ദേശങ്ങൾ കാണിക്കുന്നു.</translation>
 <translation id="5704272569086782895">ത്രെഡുചെയ്‌ത GPU റാസ്റ്ററൈസേഷൻ പ്രവർത്തനക്ഷമമാക്കുക.</translation>
-<translation id="570544101664452060">പരീക്ഷണാത്മക WebUsb അറിയിപ്പുകൾ.</translation>
 <translation id="5706551819490830015">ബില്ലിംഗ് വിലാസങ്ങൾ നിയന്ത്രിക്കുക...</translation>
 <translation id="5707185214361380026">ഇതിൽ നിന്ന് വിപുലീകരണം ലോഡുചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു:</translation>
 <translation id="5707604204219538797">അടുത്ത വാക്ക്</translation>
@@ -3465,7 +3460,6 @@
 <translation id="5900302528761731119">Google പ്രൊഫൈൽ ഫോട്ടോ</translation>
 <translation id="5900623698597156974">ഒരു TLS 1.0 ഫാൾബാക്കിന് സെർവറുമായി കണക്ഷൻ സ്ഥാപിക്കാൻ കഴിയുമായിരുന്നുവെങ്കിലും, ഞങ്ങൾ ഇനി TLS 1.0 ഫാൾബാക്കുകൾ അംഗീകരിക്കില്ല. പതിപ്പ് മാറ്റം ശരിയായി നടപ്പിലാക്കാനും പ്രത്യേകിച്ച് TLS 1.2-നെ പിന്തുണയ്‌ക്കാനും സെർവർ അപ്‌ഡേറ്റുചെയ്യേണ്ടതുണ്ട്.</translation>
 <translation id="590253956165195626">നിങ്ങൾ വായിക്കുന്ന ഭാഷയിൽ ഉള്ളതല്ലാത്ത പേജുകൾ വിവർത്തനം ചെയ്യുന്നത് വാഗ്ദാനം ചെയ്യുന്നു.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{ഒരു ഇനം}other{# ഇനങ്ങൾ}}</translation>
 <translation id="5904093760909470684">പ്രോക്സി ക്രമീകരണം</translation>
 <translation id="5906065664303289925">ഹാര്‍ഡ്‌വെയര്‍ വിലാസം:</translation>
 <translation id="5910363049092958439">ചിത്രം ഇതായി സംരക്ഷി&amp;ക്കുക...</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb
index 7587f14a..cf595c1 100644
--- a/chrome/app/resources/generated_resources_mr.xtb
+++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">यापैकी कोणत्याही USB डिव्हाइसेसवर प्रवेश करा</translation>
 <translation id="1038168778161626396">केवळ एनसिफर</translation>
 <translation id="1038842779957582377">अज्ञात नाव</translation>
-<translation id="1040931876666128942">WebUsb सूचना.</translation>
 <translation id="1042174272890264476">आपला संगणक देखील <ph name="SHORT_PRODUCT_NAME" />च्या RLZ वाचनालयासह अंगभूत आला आहे. एका विशिष्ट जाहिरात मोहीमेद्वारे चालविलेला शोध आणि <ph name="SHORT_PRODUCT_NAME" /> वापर मोजण्यासाठी RLZ एक अद्वितीय-नसलेला, वैयक्तिकरित्या-ओळखता न येणारा टॅग नियुक्त करते. <ph name="PRODUCT_NAME" /> मधील Google शोध क्वेरींमध्ये ही लेबल काहीवेळा दिसतात.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> आपल्या डिव्हाइसवर मोठ्या प्रमाणावर डेटा कायमचा संचयित करू इच्छित आहे.</translation>
 <translation id="1045157690796831147">लिप्यंतरण (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">नवीन कुकी सेटिंग्ज हे पृष्ठ रीलोड केल्यानंतर प्रभावी होतील.</translation>
 <translation id="14720830734893704">व्हर्च्युअल कीबोर्ड समर्थन सक्षम करा.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" अपलोड केली नाही. आपल्या Google ड्राइव्हमध्ये पर्याप्त स्थान नाही.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 संकेतशब्द}one{# संकेतशब्द}other{# संकेतशब्द}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />विविधोपयोगी क्षेत्रातून<ph name="END_LINK" /> शोध घेत असताना कोणते शोध इंजिन वापरले जावे हे सेट करा.</translation>
 <translation id="1477301030751268706">ओळख API टोकन कॅशे</translation>
 <translation id="1478340334823509079">तपशील: <ph name="FILE_NAME" /></translation>
@@ -928,6 +926,7 @@
 <translation id="2326606747676847821">गुप्त व्हा</translation>
 <translation id="2326931316514688470">&amp;अ‍ॅप रीलोड करा</translation>
 <translation id="2327492829706409234">अ‍ॅप सक्षम करा</translation>
+<translation id="2329597144923131178">आपल्‍या सर्व डिव्‍हाइसेस वरील आपले बुकमार्क, इतिहास, संकेतशब्द आणि इतर सेटिंग्ज मिळविण्‍यासाठी साइन इन करा.</translation>
 <translation id="2332131598580221120">स्टोअर मध्ये पहा</translation>
 <translation id="2332742915001411729">डीफॉल्टवर रीसेट करा</translation>
 <translation id="2335122562899522968">हे पृष्ठ कुकीज सेट करते.</translation>
@@ -951,7 +950,6 @@
 <translation id="2359808026110333948">सुरू ठेवा</translation>
 <translation id="236128817791440714">शिफारस केलेले: Android साठी Smart Lock सेट करा</translation>
 <translation id="236141728043665931">मायक्रोफोन प्रवेश नेहमी अवरोधित करा</translation>
-<translation id="2365626167708453863">आपल्‍या Google Smart Lock मधून खाते निवडा</translation>
 <translation id="2367972762794486313">अ‍ॅप्स दर्शवा</translation>
 <translation id="2368075211218459617">संदर्भीय शोध सक्षम करा.</translation>
 <translation id="2370882663124746154">Double-Pinyin मोड सक्षम करा</translation>
@@ -2662,7 +2660,6 @@
 <translation id="4780374166989101364">प्रायोगिक विस्तार API सक्षम करते. विस्तार गॅलरी आपल्याला प्रायोगिक API वापरत असलेले विस्तार अपलोड करण्याची परवानगी देत नाही हे लक्षात ठेवा.</translation>
 <translation id="4781787911582943401">स्क्रीनची झूम वाढवा</translation>
 <translation id="4782449893814226250">या पृष्‍ठास भेट देणे ठीक आहे का ते आपण आपल्‍या पालकांना विचारले.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}one{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint सादरीकरण</translation>
 <translation id="4785040501822872973">हा संगणक <ph name="LOGOUT_TIME_LEFT" /> सेकंदांमध्ये रीसेट होईल.
 एक्सप्लोर करणे सुरू ठेवण्यासाठी कोणतीही की दाबा.</translation>
@@ -3194,7 +3191,6 @@
 <translation id="5527474464531963247">आपण वेगळे नेटवर्क देखील निवडू शकता.</translation>
 <translation id="5527963985407842218">वाचक मोड ट्रिगर करणे</translation>
 <translation id="5528368756083817449">बुकमार्क व्यवस्थापक</translation>
-<translation id="5529098031581368697">वर्तमान वॉलपेपर '<ph name="APP_NAME" />' द्वारे सेट केला आहे</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">जागतिक</translation>
 <translation id="5533555070048896610">लिप्यंतरण (namaste → नमस्ते)</translation>
@@ -3309,7 +3305,6 @@
 <translation id="5702898740348134351">शोध इंजिने &amp;संपादित करा...</translation>
 <translation id="5703594190584829406">ड्रॉपडाउन ऐवजी कीबोर्डच्या शीर्षस्थानी स्वयं-भरण सूचना दर्शविते.</translation>
 <translation id="5704272569086782895">थ्रेड असलेले GPU रास्टराइझेशन सक्षम करा.</translation>
-<translation id="570544101664452060">प्रायोगिक WebUsb सूचना.</translation>
 <translation id="5706551819490830015">बिलिंग पत्ते व्यवस्थापित करा...</translation>
 <translation id="5707185214361380026">यावरून विस्तार लोड करण्यात अयशस्वी:</translation>
 <translation id="5707604204219538797">पुढील शब्द</translation>
@@ -3458,7 +3453,6 @@
 <translation id="5900302528761731119">Google प्रोफाइल फोटो</translation>
 <translation id="5900623698597156974">TLS 1.0 फॉलबॅक सर्व्हरशी हस्तांदोलन करण्यात सक्षम होते, परंतु आम्ही यापुढे TLS 1.0 फॉलबॅक स्वीकारणार नाही. आवृत्ती निवड योग्यरित्या लागू करण्‍यासाठी आणि प्राधान्याने TLS 1.2 ला समर्थन देण्‍यासाठी सर्व्हर अद्यतनित करणे आवश्‍यक आहे.</translation>
 <translation id="590253956165195626">आपण वाचत असलेल्या भाषेमध्ये नसलेल्या पृष्ठांचे भाषांतर करण्याचा प्रस्ताव द्या.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 आयटम}one{# आयटम}other{# आयटम}}</translation>
 <translation id="5904093760909470684">प्रॉक्झी कॉन्फिगरेशन</translation>
 <translation id="5906065664303289925">हार्डवेअरचा पत्ता:</translation>
 <translation id="5910363049092958439">म्हणून प्रतिमा ज&amp;तन करा...</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb
index 0123cc3..8189a74 100644
--- a/chrome/app/resources/generated_resources_ms.xtb
+++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Akses mana-mana peranti USB ini</translation>
 <translation id="1038168778161626396">Encipher Sahaja</translation>
 <translation id="1038842779957582377">nama tidak diketahui</translation>
-<translation id="1040931876666128942">Pemberitahuan WebUsb.</translation>
 <translation id="1042174272890264476">Komputer anda juga disertakan dengan pustaka RLZ <ph name="SHORT_PRODUCT_NAME" /> terbina dalam. RLZ memperuntukkan tanda nama tidak unik yang tidak boleh mengenal pasti secara peribadi untuk mengukur carian dan penggunaan <ph name="SHORT_PRODUCT_NAME" /> yang didorong oleh kempen galakan tertentu. Label ini kadangkala dipaparkan dalam pertanyaan Carian Google dalam <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> mahu menyimpan data yang besar pada peranti anda secara kekal.</translation>
 <translation id="1045157690796831147">Pengalihan huruf (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Tetapan kuki baharu akan berkesan selepas memuatkan semula halaman.</translation>
 <translation id="14720830734893704">Dayakan sokongan papan kekunci maya.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" tidak dimuat naik. Ruang kosong tidak mencukupi dalam Google Drive anda.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 kata laluan}other{# kata laluan}}</translation>
 <translation id="1476949146811612304">Tetapkan enjin carian mana digunakan ketika mencari dari <ph name="BEGIN_LINK" />kotak omni<ph name="END_LINK" /> .</translation>
 <translation id="1477301030751268706">Cache Token API Identiti</translation>
 <translation id="1478340334823509079">Butiran: <ph name="FILE_NAME" /></translation>
@@ -933,6 +931,7 @@
 <translation id="2326606747676847821">Gunakan Inkognito</translation>
 <translation id="2326931316514688470">&amp;Muat semula apl</translation>
 <translation id="2327492829706409234">Dayakan apl</translation>
+<translation id="2329597144923131178">Log masuk untuk mendapatkan penanda halaman, sejarah, kata laluan dan tetapan lain pada semua peranti anda.</translation>
 <translation id="2332131598580221120">Lihat di gedung</translation>
 <translation id="2332742915001411729">Tetapkan semula kepada lalai</translation>
 <translation id="2335122562899522968">Halaman ini menetapkan kuki.</translation>
@@ -956,7 +955,6 @@
 <translation id="2359808026110333948">Teruskan</translation>
 <translation id="236128817791440714">Disyorkan: Sediakan Smart Lock untuk Android</translation>
 <translation id="236141728043665931">Sentiasa sekat akses mikrofon</translation>
-<translation id="2365626167708453863">Pilih akaun daripada Google Smart Lock anda</translation>
 <translation id="2367972762794486313">Paparkan apl</translation>
 <translation id="2368075211218459617">Dayakan Carian Kontekstual.</translation>
 <translation id="2370882663124746154">Dayakan mod Pinyin Ganda</translation>
@@ -2674,7 +2672,6 @@
 <translation id="4780374166989101364">Mendayakan sambungan percubaan API. Perhatikan bahawa galeri sambungan tidak membenarkan anda untuk memuat naik sambungan yang menggunakan API percubaan.</translation>
 <translation id="4781787911582943401">Zum masuk skrin</translation>
 <translation id="4782449893814226250">Anda telah bertanya kepada ibu bapa anda sama ada ok untuk melawat halaman ini.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Persembahan PowerPoint</translation>
 <translation id="4785040501822872973">Komputer ini akan ditetapkan semula dalam <ph name="LOGOUT_TIME_LEFT" /> saat.
 Tekan sebarang kekunci untuk terus meneroka.</translation>
@@ -3205,7 +3202,6 @@
 <translation id="5527474464531963247">Anda juga boleh memilih rangkaian lain.</translation>
 <translation id="5527963985407842218">Pencetusan Mod Pembaca</translation>
 <translation id="5528368756083817449">Pengurus Penanda Halaman</translation>
-<translation id="5529098031581368697">Kertas dinding semasa ditetapkan oleh '<ph name="APP_NAME" />'</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Pengalihan huruf (namaste → नमस्ते)</translation>
@@ -3321,7 +3317,6 @@
 <translation id="5702898740348134351">&amp;Edit Enjin Carian...</translation>
 <translation id="5703594190584829406">Tunjukkan cadangan Autolengkap di atas papan kekunci bukannya dalam menu lungsur.</translation>
 <translation id="5704272569086782895">Dayakan proses raster GPU berurutan.</translation>
-<translation id="570544101664452060">Pemberitahuan WebUsb percubaan.</translation>
 <translation id="5706551819490830015">Mengurus alamat pengebilan...</translation>
 <translation id="5707185214361380026">Gagal memuatkan sambungan daripada:</translation>
 <translation id="5707604204219538797">Perkataan seterusnya</translation>
@@ -3470,7 +3465,6 @@
 <translation id="5900302528761731119">Foto Profil Google</translation>
 <translation id="5900623698597156974">Jatuh balik TLS 1.0 dapat berjabat tangan dengan pelayan tetapi kami tidak lagi menerima jatuh balik TLS 1.0. Pelayan perlu dikemaskinikan untuk melaksanakan rundingan versi dengan betul dan sebaik-baiknya menyokong TLS 1.2.</translation>
 <translation id="590253956165195626">Tawaran untuk menterjemah halaman yang bukan dalam bahasa yang anda baca.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 item}other{# item}}</translation>
 <translation id="5904093760909470684">Konfigurasi Proksi</translation>
 <translation id="5906065664303289925">Alamat perkakasan:</translation>
 <translation id="5910363049092958439">Si&amp;mpan Imej Sebagai...</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb
index a35766c..01b991c 100644
--- a/chrome/app/resources/generated_resources_nl.xtb
+++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Toegang verkrijgen tot een van deze USB-apparaten</translation>
 <translation id="1038168778161626396">Alleen coderen</translation>
 <translation id="1038842779957582377">onbekende naam</translation>
-<translation id="1040931876666128942">WebUSB-meldingen.</translation>
 <translation id="1042174272890264476">Je computer is ook uitgerust met de RLZ-bibliotheek van <ph name="SHORT_PRODUCT_NAME" />. RLZ wijst een niet-unieke, niet-persoonlijke tag toe om de zoekopdrachten en het gebruik van <ph name="SHORT_PRODUCT_NAME" /> te meten als gevolg van een bepaalde promotiecampagne. Deze labels worden soms weergegeven in Google-zoekopdrachten in <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> wil grote gegevens permanent op je apparaat opslaan.</translation>
 <translation id="1045157690796831147">Transliteratie (namaskar → നമസ്കാരം)</translation>
@@ -175,7 +174,7 @@
 <translation id="1227507814927581609">Verificatie mislukt tijdens verbinden met '<ph name="DEVICE_NAME" />'.</translation>
 <translation id="1231728991993914119">Melding bij sluiten inschakelen voor gehoste apps.</translation>
 <translation id="1232569758102978740">Naamloos</translation>
-<translation id="1233721473400465416">Taal</translation>
+<translation id="1233721473400465416">Landinstelling</translation>
 <translation id="1234808891666923653">Service Workers</translation>
 <translation id="123578888592755962">Schijf is vol</translation>
 <translation id="1240892293903523606">DOM Inspector</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">De nieuwe cookie-instellingen worden van kracht nadat de pagina opnieuw is geladen.</translation>
 <translation id="14720830734893704">Hiermee schakel je ondersteuning voor een virtueel toetsenbord in.</translation>
 <translation id="1474339897586437869">'<ph name="FILENAME" />' is niet geüpload. Er is onvoldoende ruimte beschikbaar in je Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 wachtwoord}other{# wachtwoorden}}</translation>
 <translation id="1476949146811612304">Instellen welke zoekmachine wordt gebruikt bij het zoeken via de <ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Tokencache van Identity API</translation>
 <translation id="1478340334823509079">Details: <ph name="FILE_NAME" /></translation>
@@ -920,6 +918,7 @@
 <translation id="2326606747676847821">Incognito gaan</translation>
 <translation id="2326931316514688470">App opnieuw &amp;laden</translation>
 <translation id="2327492829706409234">App inschakelen</translation>
+<translation id="2329597144923131178">Log in om je bladwijzers, geschiedenis, wachtwoorden en andere instellingen op al je apparaten te gebruiken.</translation>
 <translation id="2332131598580221120">Bekijken in de Web Store</translation>
 <translation id="2332742915001411729">Terugzetten naar standaardinstelling</translation>
 <translation id="2335122562899522968">Deze pagina stelt cookies in.</translation>
@@ -943,7 +942,6 @@
 <translation id="2359808026110333948">Doorgaan</translation>
 <translation id="236128817791440714">Aanbevolen: stel Smart Lock voor Android in</translation>
 <translation id="236141728043665931">Microfoontoegang altijd blokkeren</translation>
-<translation id="2365626167708453863">Een account kiezen uit je Google Smart Lock</translation>
 <translation id="2367972762794486313">Apps weergeven</translation>
 <translation id="2368075211218459617">Contextueel zoeken inschakelen.</translation>
 <translation id="2370882663124746154">Double-pinyinmethode inschakelen</translation>
@@ -2659,7 +2657,6 @@
 <translation id="4780374166989101364">Hiermee worden experimentele extensie-API's ingeschakeld. Je kunt geen extensies naar de extensiegalerij uploaden die gebruikmaken van experimentele API's.</translation>
 <translation id="4781787911582943401">Scherm inzoomen</translation>
 <translation id="4782449893814226250">Je hebt je ouders gevraagd of je deze pagina mag bezoeken.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}other{# KB}}</translation>
 <translation id="4784330909746505604">PowerPoint-presentatie</translation>
 <translation id="4785040501822872973">Deze computer wordt over <ph name="LOGOUT_TIME_LEFT" /> seconden opnieuw ingesteld.
 Druk op een toets om door te gaan met verkennen.</translation>
@@ -3189,7 +3186,6 @@
 <translation id="5527474464531963247">Je kunt ook een ander netwerk selecteren.</translation>
 <translation id="5527963985407842218">Activering van knop 'Lezermodus'Reader Mode triggering</translation>
 <translation id="5528368756083817449">Bladwijzerbeheer</translation>
-<translation id="5529098031581368697">Huidige achtergrond is ingesteld door '<ph name="APP_NAME" />'</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Algemeen</translation>
 <translation id="5533555070048896610">Transliteratie (namaste → नमस्ते)</translation>
@@ -3305,7 +3301,6 @@
 <translation id="5702898740348134351">Zo&amp;ekmachines bewerken...</translation>
 <translation id="5703594190584829406">Geeft suggesties van Automatisch aanvullen boven op het toetsenbord weer in plaats van in een dropdown-menu.</translation>
 <translation id="5704272569086782895">Threaded GPU-rasterfunctie inschakelen.</translation>
-<translation id="570544101664452060">Experimentele WebUSB-meldingen.</translation>
 <translation id="5706551819490830015">Factureringsadressen beheren...</translation>
 <translation id="5707185214361380026">Laden van extensie mislukt vanuit:</translation>
 <translation id="5707604204219538797">Volgend woord</translation>
@@ -3454,7 +3449,6 @@
 <translation id="5900302528761731119">Google-profielfoto</translation>
 <translation id="5900623698597156974">Een TLS 1.0 fallback kan communiceren met de server, maar we accepteren geen TLS 1.0 fallbacks meer. De server moet worden geüpdatet zodat de versieonderhandeling correct wordt geïmplementeerd en bij voorkeur TLS 1.2 wordt ondersteund.</translation>
 <translation id="590253956165195626">Aanbieden om pagina’s te vertalen die in een voor jou onbekende taal zijn.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 item}other{# items}}</translation>
 <translation id="5904093760909470684">Proxyconfiguratie</translation>
 <translation id="5906065664303289925">Hardware-adres:</translation>
 <translation id="5910363049092958439">Af&amp;beelding opslaan als...</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb
index 400aebe..0974d80 100644
--- a/chrome/app/resources/generated_resources_no.xtb
+++ b/chrome/app/resources/generated_resources_no.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Les enhver av disse USB-enhetene</translation>
 <translation id="1038168778161626396">Kun chiffrering</translation>
 <translation id="1038842779957582377">ukjent navn</translation>
-<translation id="1040931876666128942">WebUsb-varsler.</translation>
 <translation id="1042174272890264476">Datamaskinen din har <ph name="SHORT_PRODUCT_NAME" />s RLZ-bibliotek innebygget. RLZ tildeler en ikke-unik, ikke-personlig tagg for å måle søk og <ph name="SHORT_PRODUCT_NAME" />-bruk drevet av en bestemt markedsføringskampanje. Disse etikettene vises noen ganger i Google-søk i <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> ønsker å lagre store datamengder på enheten din permanent.</translation>
 <translation id="1045157690796831147">Translitterasjon (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Nye innstillinger for informasjonskapsler trer i kraft etter siden er lastet inn på nytt.</translation>
 <translation id="14720830734893704">Aktiver støtte for virtuelt tastatur.</translation>
 <translation id="1474339897586437869">«<ph name="FILENAME" />» ble ikke lastet opp. Det er ikke nok ledig plass på Google Disk.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 passord}other{# passord}}</translation>
 <translation id="1476949146811612304">Angi hvilken søkemotor som brukes når du søker i <ph name="BEGIN_LINK" />søkefeltet<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Tokenbuffer for identitets-API</translation>
 <translation id="1478340334823509079">Detaljer: <ph name="FILE_NAME" /></translation>
@@ -910,7 +908,7 @@
 <translation id="2309760508720442723">Det finnes problemer med nettstedets sertifikatkjede (<ph name="CERT_ERROR_DESCRIPTION" />).</translation>
 <translation id="2312980885338881851">Ojsann! Det ser ut til at du ikke har noen eksisterende overvåkende brukere å importere. Opprett én eller flere fra en annen enhet, og så kan du importere dem hit etterpå.</translation>
 <translation id="2314244639364647639">{NUM_ITEMS,plural, =1{Dette sletter minst $1 element permanent fra denne enheten, men fjerner ikke synkroniserte elementer fra andre enheter.}other{Dette sletter minst $1 elementer permanent fra denne enheten, men fjerner ikke synkroniserte elementer fra andre enheter.}}</translation>
-<translation id="2316129865977710310">Nei takk</translation>
+<translation id="2316129865977710310">Nei, takk</translation>
 <translation id="2317031807364506312">AVBRYT</translation>
 <translation id="2318143611928805047">Papirstørrelse</translation>
 <translation id="2320435940785160168">Tjeneren krever et autentiseringssertifikat og godkjente ikke sertifikatet som ble sendt av         nettleseren.
@@ -922,6 +920,7 @@
 <translation id="2326606747676847821">Start inkognitomodus</translation>
 <translation id="2326931316514688470">&amp;Last inn appen på nytt</translation>
 <translation id="2327492829706409234">Aktiver appen</translation>
+<translation id="2329597144923131178">Logg på for å få bokmerkene, loggen, passordene og de andre innstillingene dine på alle enhetene du bruker.</translation>
 <translation id="2332131598580221120">Se i Nettmarked</translation>
 <translation id="2332742915001411729">Tilbakestill til standard</translation>
 <translation id="2335122562899522968">Denne siden plasserer informasjonskapsler på datamaskinen.</translation>
@@ -945,7 +944,6 @@
 <translation id="2359808026110333948">Fortsett</translation>
 <translation id="236128817791440714">Anbefalt: Konfigurer Smart Lock for Android</translation>
 <translation id="236141728043665931">Blokkér alltid bruk av mikrofonen</translation>
-<translation id="2365626167708453863">Velg en konto fra Google Smart Lock</translation>
 <translation id="2367972762794486313">Vis apper</translation>
 <translation id="2368075211218459617">Aktiver kontekstbasert søk.</translation>
 <translation id="2370882663124746154">Aktiver modusen Dobbel pinyin</translation>
@@ -2653,7 +2651,6 @@
 <translation id="4780374166989101364">Aktiverer grensesnitt for eksperimentelle utvidelser. Merk at dette utvidelsesgalleriet ikke tillater deg å laste opp utvidelser som bruker eksperimentelle grensesnitt.</translation>
 <translation id="4781787911582943401">Zoom på skjermen</translation>
 <translation id="4782449893814226250">Du spurte foreldrene dine om det er greit å besøke denne siden.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint-presentasjon</translation>
 <translation id="4785040501822872973">Denne datamaskinen starter på nytt om <ph name="LOGOUT_TIME_LEFT" /> sekunder.
 Trykk på en tast for å fortsette økten.</translation>
@@ -3181,7 +3178,6 @@
 <translation id="5527474464531963247">Du kan også velge et annet nettverk.</translation>
 <translation id="5527963985407842218">Utløsing av lesermodus</translation>
 <translation id="5528368756083817449">Bokmerkebehandling</translation>
-<translation id="5529098031581368697">Gjeldende bakgrunn er angitt av «<ph name="APP_NAME" />»</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Overordnet</translation>
 <translation id="5533555070048896610">Translitterasjon (namaste → नमस्ते)</translation>
@@ -3297,7 +3293,6 @@
 <translation id="5702898740348134351">R&amp;ediger søkemotorer</translation>
 <translation id="5703594190584829406">Viser autofyll-forslag over tastaturet i stedet for i en rullegardinmeny.</translation>
 <translation id="5704272569086782895">Slå på trådbasert GPU-rastering.</translation>
-<translation id="570544101664452060">Eksperimentelle WebUsb-varsler.</translation>
 <translation id="5706551819490830015">Administrer faktureringsadresser</translation>
 <translation id="5707185214361380026">Kunne ikke laste inn utvidelse fra:</translation>
 <translation id="5707604204219538797">Neste ord</translation>
@@ -3443,7 +3438,6 @@
 <translation id="5900302528761731119">Google-profilbilde</translation>
 <translation id="5900623698597156974">En TLS 1.0-reserve greide å utveksle håndtrykk med tjeneren, men vi godtar ikke TLS 1.0-reserver lenger. Tjeneren må oppdateres slik at den implementerer versjonsbehandling riktig, og den bør støtte TLS 1.2.</translation>
 <translation id="590253956165195626">Tilby oversettelse av nettsider på språk du ikke kan lese.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 vare}other{# varer}}</translation>
 <translation id="5904093760909470684">Konfigurasjon av mellomtjener</translation>
 <translation id="5906065664303289925">Maskinvareadresse:</translation>
 <translation id="5910363049092958439">Lagre &amp;bildet som</translation>
@@ -4406,7 +4400,7 @@
 <translation id="7375125077091615385">Type:</translation>
 <translation id="7377169924702866686">Caps Lock er på.</translation>
 <translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> – <ph name="FULL_DATE" /></translation>
-<translation id="7378627244592794276">Nei takk</translation>
+<translation id="7378627244592794276">Nei, takk</translation>
 <translation id="7378810950367401542">/</translation>
 <translation id="7382160026931194400">Lagrede |innholdsinnstillinger| og #søkemotorer# fjernes ikke, og disse kan inneholde informasjon om surfevanene dine.</translation>
 <translation id="7385854874724088939">Det oppstod en feil under forsøket på å skrive ut. Kontroller skriveren og prøv igjen.</translation>
@@ -4475,7 +4469,7 @@
 <translation id="7469894403370665791">Koble til dette nettverket automatisk</translation>
 <translation id="747114903913869239">Feil: Kan ikke avkode etternavnet</translation>
 <translation id="7472639616520044048">MIME-typer:</translation>
-<translation id="7473891865547856676">Nei takk</translation>
+<translation id="7473891865547856676">Nei, takk</translation>
 <translation id="747459581954555080">Gjenopprett alt</translation>
 <translation id="7474669101120914750">Denne innstillingen styres av utvidelsen <ph name="NAME" /></translation>
 <translation id="7474889694310679759">Engelsk tastatur (Canada)</translation>
@@ -4701,7 +4695,7 @@
 <translation id="7800304661137206267">Tilkoblingen er kryptert ved hjelp av <ph name="CIPHER" />, med <ph name="MAC" /> for autentisering av meldinger og <ph name="KX" /> som nøkkelutvekslingsmekanisme.</translation>
 <translation id="7800518121066352902">Rotér m&amp;ot klokken</translation>
 <translation id="7801746894267596941">Bare folk som har passordfrasen din kan lese de krypterte dataene dine – passordfrasen hverken sendes til eller lagres av Google. Hvis du glemmer den, må du</translation>
-<translation id="780301667611848630">Nei takk</translation>
+<translation id="780301667611848630">Nei, takk</translation>
 <translation id="7805768142964895445">Status</translation>
 <translation id="7806513705704909664">Aktivér autofyll for å fylle ut nettskjemaer med ett enkelt klikk.</translation>
 <translation id="7807711621188256451">Tillat alltid at <ph name="HOST" /> bruker kameraet ditt</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb
index c282e58c..2e99a85 100644
--- a/chrome/app/resources/generated_resources_pl.xtb
+++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Uzyskaj dostęp do dowolnego z tych urządzeń USB</translation>
 <translation id="1038168778161626396">Tylko szyfrowanie</translation>
 <translation id="1038842779957582377">nieznana nazwa</translation>
-<translation id="1040931876666128942">Powiadomienia WebUsb.</translation>
 <translation id="1042174272890264476">Twój komputer zawiera również wbudowaną bibliotekę RLZ <ph name="SHORT_PRODUCT_NAME" />. Przypisuje ona powtarzalny, nieumożliwiający identyfikacji użytkownika tag służący do monitorowania wyszukiwań i używania <ph name="SHORT_PRODUCT_NAME" /> w ramach określonej kampanii promocyjnej. Etykiety te czasami pojawiają się w zapytaniach wyszukiwarki Google w <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285">Witryna <ph name="URL" /> chce na stałe przechowywać dużą ilość danych na Twoim urządzeniu.</translation>
 <translation id="1045157690796831147">Transliteracja (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Nowe ustawienia plików cookie zostaną zastosowane po ponownym załadowaniu strony.</translation>
 <translation id="14720830734893704">Włącz obsługę klawiatury wirtualnej.</translation>
 <translation id="1474339897586437869">Plik „<ph name="FILENAME" />” nie został przesłany. Za mało wolnego miejsca na Dysku Google.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 hasło}few{# hasła}many{# haseł}other{# hasła}}</translation>
 <translation id="1476949146811612304">Wybierz wyszukiwarkę używaną w <ph name="BEGIN_LINK" />omniboksie<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Pamięć podręczna tokenów interfejsu API Identity</translation>
 <translation id="1478340334823509079">Szczegóły: <ph name="FILE_NAME" /></translation>
@@ -922,6 +920,7 @@
 <translation id="2326606747676847821">Włącz tryb incognito</translation>
 <translation id="2326931316514688470">P&amp;rzeładuj aplikację</translation>
 <translation id="2327492829706409234">Włącz aplikację</translation>
+<translation id="2329597144923131178">Zaloguj się, by korzystać z zakładek, historii, haseł i innych ustawień na wszystkich swoich urządzeniach.</translation>
 <translation id="2332131598580221120">Wyświetl w sklepie</translation>
 <translation id="2332742915001411729">Przywróć domyślne</translation>
 <translation id="2335122562899522968">Ta strona ustawia pliki cookie.</translation>
@@ -945,7 +944,6 @@
 <translation id="2359808026110333948">Kontynuuj</translation>
 <translation id="236128817791440714">Zalecane: skonfiguruj Smart Lock na Androida</translation>
 <translation id="236141728043665931">Zawsze blokuj dostęp do mikrofonu</translation>
-<translation id="2365626167708453863">Wybierz konto w Google Smart Lock</translation>
 <translation id="2367972762794486313">Pokaż aplikacje</translation>
 <translation id="2368075211218459617">Włącz Wyszukiwanie kontekstowe.</translation>
 <translation id="2370882663124746154">Włącz tryb „podwójny pinyin”</translation>
@@ -1444,7 +1442,7 @@
 <translation id="3031417829280473749">Agentka X</translation>
 <translation id="3031557471081358569">Wybierz elementy do zaimportowania:</translation>
 <translation id="3033332627063280038">Włącz eksperymentalną implementację dyrektywy stale-while-revalidate funkcji Cache-Control. Pozwala to serwerom na określenie, że w tle może być przeprowadzane przywracanie ważności w przypadku niektórych zasobów, by zmniejszyć czas oczekiwania.</translation>
-<translation id="3037605927509011580">Niedobrze!</translation>
+<translation id="3037605927509011580">Kurza twarz!</translation>
 <translation id="3039828483675273919">Przenoszę $1 elementy(ów)...</translation>
 <translation id="304009983491258911">Zmień PIN karty SIM</translation>
 <translation id="3041612393474885105">Informacje o certyfikacie</translation>
@@ -2652,7 +2650,6 @@
 <translation id="4780374166989101364">Włącza eksperymentalne interfejsy API rozszerzeń. Należy pamiętać, że galeria rozszerzeń nie dopuszcza przesyłania rozszerzeń korzystających z eksperymentalnych interfejsów API.</translation>
 <translation id="4781787911582943401">Powiększ ekran</translation>
 <translation id="4782449893814226250">Zapytałeś rodziców, czy możesz wejść na tę stronę.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}few{# kB}many{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Prezentacja PowerPoint</translation>
 <translation id="4785040501822872973">Ten komputer zostanie zresetowany za <ph name="LOGOUT_TIME_LEFT" /> s.
 Naciśnij dowolny klawisz, by kontynuować przeglądanie.</translation>
@@ -3184,7 +3181,6 @@
 <translation id="5527474464531963247">Możesz także wybrać inną sieć.</translation>
 <translation id="5527963985407842218">Włączanie trybu czytnika</translation>
 <translation id="5528368756083817449">Menedżer zakładek</translation>
-<translation id="5529098031581368697">Aktualna tapeta została ustawiona przez aplikację „<ph name="APP_NAME" />”</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Globalne</translation>
 <translation id="5533555070048896610">Transliteracja (namaste → नमस्ते)</translation>
@@ -3300,7 +3296,6 @@
 <translation id="5702898740348134351">&amp;Edytuj wyszukiwarki...</translation>
 <translation id="5703594190584829406">Pokazuje sugestie autouzupełniania nad klawiaturą, a nie na liście.</translation>
 <translation id="5704272569086782895">Włącz rasteryzację GPU w wątkach.</translation>
-<translation id="570544101664452060">Eksperymentalne powiadomienia WebUsb.</translation>
 <translation id="5706551819490830015">Zarządzaj adresami rozliczeniowymi...</translation>
 <translation id="5707185214361380026">Nie udało się wczytać rozszerzenia z:</translation>
 <translation id="5707604204219538797">Następne słowo</translation>
@@ -3449,7 +3444,6 @@
 <translation id="5900302528761731119">Zdjęcie z profilu Google</translation>
 <translation id="5900623698597156974">Udało się skontaktować z serwerem przy użyciu starszej wersji protokołu TLS (1.0), ale nie akceptujemy już połączeń z tą wersją. Serwer wymaga aktualizacji, by prawidłowo negocjował wersje i (optymalnie) obsługiwał TLS 1.2.</translation>
 <translation id="590253956165195626">Proponuj tłumaczenie stron w obcych językach.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 element}few{# elementy}many{# elementów}other{# elementu}}</translation>
 <translation id="5904093760909470684">Konfiguracja serwera proxy</translation>
 <translation id="5906065664303289925">Adres sprzętowy:</translation>
 <translation id="5910363049092958439">Zapisz gra&amp;fikę jako...</translation>
@@ -3991,7 +3985,7 @@
 <translation id="6736045498964449756">Ups, hasła nie pasują do siebie.</translation>
 <translation id="6736329909263487977"><ph name="ISSUED_BY" /> [<ph name="ISSUED_TO" />]</translation>
 <translation id="6739254200873843030">Ważność karty wygasła. Sprawdź datę lub podaj nową kartę.</translation>
-<translation id="6740234557573873150">Wstrzymano – <ph name="FILE_NAME" /></translation>
+<translation id="6740234557573873150">Wstrzymano pobieranie <ph name="FILE_NAME" /></translation>
 <translation id="6740369132746915122">Jeśli rozumiesz zagrożenie, możesz <ph name="BEGIN_LINK" />wejść na tę niebezpieczną stronę<ph name="END_LINK" />.</translation>
 <translation id="6745592621698551453">Aktualizuj teraz</translation>
 <translation id="6745994589677103306">Nic nie rób</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb
index 129b682f..6b7d0766 100644
--- a/chrome/app/resources/generated_resources_pt-BR.xtb
+++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Acessar qualquer um desses dispositivos USB</translation>
 <translation id="1038168778161626396">Somente codificar</translation>
 <translation id="1038842779957582377">nome desconhecido</translation>
-<translation id="1040931876666128942">Notificações WebUsb.</translation>
 <translation id="1042174272890264476">Seu computador já vem com a biblioteca RLZ do <ph name="SHORT_PRODUCT_NAME" /> integrada. O RLZ atribui uma tag não exclusiva e sem identificação pessoal para medir as pesquisas e o uso do <ph name="SHORT_PRODUCT_NAME" /> gerados por uma campanha promocional específica. Esses marcadores às vezes aparecem em consultas da Pesquisa do Google no <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> deseja armazenar permanentemente um grande volume de dados em seu dispositivo.</translation>
 <translation id="1045157690796831147">Transliteração (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Novas configurações de cookies entrarão em vigor depois que a página for atualizada.</translation>
 <translation id="14720830734893704">Ativar suporte ao teclado virtual.</translation>
 <translation id="1474339897586437869">Não foi feito o upload de "<ph name="FILENAME" />". Não há espaço livre suficiente no seu Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 senha}one{# senhas}other{# senhas}}</translation>
 <translation id="1476949146811612304">Defina o mecanismo de pesquisa usado na pesquisa da <ph name="BEGIN_LINK" />omnibox<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Cache do token da API de identidade</translation>
 <translation id="1478340334823509079">Detalhes: <ph name="FILE_NAME" /></translation>
@@ -922,6 +920,7 @@
 <translation id="2326606747676847821">Navegar em modo anônimo</translation>
 <translation id="2326931316514688470">&amp;Recarregar aplicativo</translation>
 <translation id="2327492829706409234">Ativar aplicativo</translation>
+<translation id="2329597144923131178">Faça login para que favoritos, histórico, senhas e outras configurações fiquem disponíveis em todos os seus dispositivos.</translation>
 <translation id="2332131598580221120">Ver na loja</translation>
 <translation id="2332742915001411729">Redefinir para os valores padrão</translation>
 <translation id="2335122562899522968">Cookies fornecidos por esta página.</translation>
@@ -945,7 +944,6 @@
 <translation id="2359808026110333948">Continuar</translation>
 <translation id="236128817791440714">Recomendado: configurar Smart Lock para Android</translation>
 <translation id="236141728043665931">Sempre bloquear o acesso ao microfone</translation>
-<translation id="2365626167708453863">Escolher uma conta no Google Smart Lock</translation>
 <translation id="2367972762794486313">Mostrar aplicativos</translation>
 <translation id="2368075211218459617">Ative a Pesquisa contextual.</translation>
 <translation id="2370882663124746154">Ativar modo Pinyin duplo</translation>
@@ -2652,7 +2650,6 @@
 <translation id="4780374166989101364">Ativa APIs de extensões experimentais. Observe que a galeria de extensões não permite que você envie extensões que usem APIs experimentais.</translation>
 <translation id="4781787911582943401">Ampliar o zoom da tela</translation>
 <translation id="4782449893814226250">Você perguntou a seus pais se podia visitar esta página.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}one{# KB}other{# KB}}</translation>
 <translation id="4784330909746505604">Apresentação do PowerPoint</translation>
 <translation id="4785040501822872973">Este computador será reiniciado em <ph name="LOGOUT_TIME_LEFT" /> segundos. Pressione qualquer tecla para continuar explorando.</translation>
 <translation id="4786993863723020412">Erro na leitura do cache</translation>
@@ -3182,7 +3179,6 @@
 <translation id="5527474464531963247">Também é possível selecionar outra rede.</translation>
 <translation id="5527963985407842218">Acionamento do modo leitor</translation>
 <translation id="5528368756083817449">Gerenciador de favoritos</translation>
-<translation id="5529098031581368697">O papel de parede atual está definido por '<ph name="APP_NAME" />'</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Transliteração (namaste → नमस्ते)</translation>
@@ -3299,7 +3295,6 @@
 <translation id="5702898740348134351">&amp;Editar mecanismos de pesquisa...</translation>
 <translation id="5703594190584829406">Mostra sugestões de preenchimento automático na parte superior do teclado em vez de em uma lista suspensa.</translation>
 <translation id="5704272569086782895">Ativar a varredura da GPU em threads.</translation>
-<translation id="570544101664452060">Notificações WebUsb experimentais.</translation>
 <translation id="5706551819490830015">Gerenciar endereços de faturamento...</translation>
 <translation id="5707185214361380026">Falha ao carregar a extensão a partir de:</translation>
 <translation id="5707604204219538797">Próxima palavra</translation>
@@ -3448,7 +3443,6 @@
 <translation id="5900302528761731119">Foto do perfil do Google</translation>
 <translation id="5900623698597156974">Um substituto de TLS 1.0 pôde fazer um handshake com o servidor, mas nós não aceitamos mais substitutos de TLS 1.0. O servidor precisa ser atualizado para implementar corretamente a negociação de versão e ser compatível, preferivelmente, com o TLS 1.2.</translation>
 <translation id="590253956165195626">Sugerir a tradução de páginas que não estão em um idioma que você conheça.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 item}one{# itens}other{# itens}}</translation>
 <translation id="5904093760909470684">Configuração de proxy</translation>
 <translation id="5906065664303289925">Endereço do hardware:</translation>
 <translation id="5910363049092958439">Sal&amp;var imagem como...</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb
index 08142e9..82fc3a6 100644
--- a/chrome/app/resources/generated_resources_pt-PT.xtb
+++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Aceder a qualquer um destes dispositivos USB</translation>
 <translation id="1038168778161626396">Cifrar apenas</translation>
 <translation id="1038842779957582377">nome desconhecido</translation>
-<translation id="1040931876666128942">Notificações WebUsb.</translation>
 <translation id="1042174272890264476">O seu computador também tem a biblioteca RLZ de <ph name="SHORT_PRODUCT_NAME" /> incorporada. A RLZ atribui uma etiqueta não exclusiva e não identificável a nível pessoal para medir as pesquisas e a utilização de <ph name="SHORT_PRODUCT_NAME" /> impulsionada por uma campanha promocional específica. Estas etiquetas por vezes aparecem em consultas da Pesquisa Google em <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> pretende armazenar definitivamente dados de grandes dimensões no seu dispositivo.</translation>
 <translation id="1045157690796831147">Transliteração (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">As novas definições de cookies terão efeito depois de recarregar a página.</translation>
 <translation id="14720830734893704">Ativa o suporte para o teclado virtual.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" não foi carregado. Não existe espaço livre suficiente no seu Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 palavra-passe}other{# palavras-passe}}</translation>
 <translation id="1476949146811612304">Defina o motor de pesquisa que será utilizado quando pesquisar a partir da
         <ph name="BEGIN_LINK" />caixa geral<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Cache do Símbolo da API de Identidade</translation>
@@ -922,6 +920,7 @@
 <translation id="2326606747676847821">Entrar no modo de navegação anónima</translation>
 <translation id="2326931316514688470">&amp;Recarregar aplicação</translation>
 <translation id="2327492829706409234">Ativar aplicação</translation>
+<translation id="2329597144923131178">Inicie sessão para aceder aos marcadores, ao histórico, às palavras-passe e a outras definições em todos os dispositivos.</translation>
 <translation id="2332131598580221120">Ver na loja</translation>
 <translation id="2332742915001411729">Repor predefinição</translation>
 <translation id="2335122562899522968">Esta página define os cookies.</translation>
@@ -945,7 +944,6 @@
 <translation id="2359808026110333948">Continuar</translation>
 <translation id="236128817791440714">Recomendado: Configurar o Smart Lock para Android</translation>
 <translation id="236141728043665931">Bloquear sempre o acesso ao microfone</translation>
-<translation id="2365626167708453863">Escolher uma conta a partir do Google Smart Lock</translation>
 <translation id="2367972762794486313">Mostrar aplicações</translation>
 <translation id="2368075211218459617">Ativar pesquisa contextual.</translation>
 <translation id="2370882663124746154">Activar modo PinYin duplo</translation>
@@ -2661,7 +2659,6 @@
 <translation id="4780374166989101364">Activa as APIs de extensões experimentais. Tenha em atenção que a galeria de extensões não permite carregar extensões que utilizem APIs experimentais.</translation>
 <translation id="4781787911582943401">Ampliar o ecrã</translation>
 <translation id="4782449893814226250">Perguntaste aos teus pais se podes aceder a esta página.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}other{# KB}}</translation>
 <translation id="4784330909746505604">Apresentação do PowerPoint</translation>
 <translation id="4785040501822872973">Este computador será reposto dentro de <ph name="LOGOUT_TIME_LEFT" /> segundos.
 Prima qualquer tecla para continuar a explorar.</translation>
@@ -3192,7 +3189,6 @@
 <translation id="5527474464531963247">Também pode selecionar outra rede.</translation>
 <translation id="5527963985407842218">Acionamento do Modo de leitor</translation>
 <translation id="5528368756083817449">Gestor de marcadores</translation>
-<translation id="5529098031581368697">A imagem de fundo atual é definida por "<ph name="APP_NAME" />"</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Transliteração (namaste → नमस्ते)</translation>
@@ -3309,7 +3305,6 @@
 <translation id="5702898740348134351">&amp;Editar motores de pesquisa...</translation>
 <translation id="5703594190584829406">Mostra sugestões de Preenchimento automático na parte superior do teclado em vez de num menu pendente.</translation>
 <translation id="5704272569086782895">Ativar rasterização GPU de threads.</translation>
-<translation id="570544101664452060">Notificações WebUsb experimentais.</translation>
 <translation id="5706551819490830015">Gerir endereços de faturação...</translation>
 <translation id="5707185214361380026">Falha ao carregar a extensão de:</translation>
 <translation id="5707604204219538797">Palavra seguinte</translation>
@@ -3458,7 +3453,6 @@
 <translation id="5900302528761731119">Fotografia do Perfil do Google</translation>
 <translation id="5900623698597156974">Uma alternativa de TLS 1.0 conseguiu estabelecer um handshake com o servidor, mas já não aceitamos alternativas de TLS 1.0. É necessário atualizar o servidor para implementar corretamente a negociação da versão e, preferencialmente, suportar TLS 1.2.</translation>
 <translation id="590253956165195626">Sugerir a tradução de páginas que não estejam num idioma que o utilizador saiba ler.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 item}other{# itens}}</translation>
 <translation id="5904093760909470684">Configuração do proxy</translation>
 <translation id="5906065664303289925">Endereço de hardware:</translation>
 <translation id="5910363049092958439">Guard&amp;ar Imagem Como...</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb
index afdfb61..075b0c89 100644
--- a/chrome/app/resources/generated_resources_ro.xtb
+++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Accesează oricare dintre aceste dispozitive USB</translation>
 <translation id="1038168778161626396">Numai cifrare</translation>
 <translation id="1038842779957582377">nume necunoscut</translation>
-<translation id="1040931876666128942">Notificări WebUsb.</translation>
 <translation id="1042174272890264476">Computerul este dotat, de asemenea, cu o bibliotecă RLZ încorporată, oferită de <ph name="SHORT_PRODUCT_NAME" />. Biblioteca RLZ atribuie o etichetă non-unică și care nu vă identifică în mod personal, pentru a măsura căutările și modul în care este utilizat <ph name="SHORT_PRODUCT_NAME" /> în funcție de o anumită campanie promoțională. Aceste etichete pot apărea uneori în interogările Căutării Google din <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> dorește să stocheze permanent cantități mari de date pe dispozitivul dvs.</translation>
 <translation id="1045157690796831147">Transliterație (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Noile setări pentru cookie-uri se vor aplica după reîncărcarea paginii.</translation>
 <translation id="14720830734893704">Activați compatibilitatea cu tastatura virtuală.</translation>
 <translation id="1474339897586437869">„<ph name="FILENAME" />” nu s-a încărcat. Nu există spațiu liber suficient în Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{O parolă}few{# parole}other{# de parole}}</translation>
 <translation id="1476949146811612304">Setați ce motor de căutare este utilizat atunci când se caută din <ph name="BEGIN_LINK" />caseta polivalentă<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Memorie cache pentru indicativele API-ului Identity</translation>
 <translation id="1478340334823509079">Detalii: <ph name="FILE_NAME" /></translation>
@@ -933,6 +931,7 @@
 <translation id="2326606747676847821">Treci în incognito</translation>
 <translation id="2326931316514688470">&amp;Reîncarcă aplicația</translation>
 <translation id="2327492829706409234">Activați aplicația</translation>
+<translation id="2329597144923131178">Conectează-te și accesează marcajele, istoricul, parolele și alte setări pe toate dispozitivele.</translation>
 <translation id="2332131598580221120">Vedeți în magazin</translation>
 <translation id="2332742915001411729">Resetați la valorile prestabilite</translation>
 <translation id="2335122562899522968">Această pagină a setat cookie-uri.</translation>
@@ -956,7 +955,6 @@
 <translation id="2359808026110333948">Continuă</translation>
 <translation id="236128817791440714">Se recomandă: configurează Smart Lock pentru Android</translation>
 <translation id="236141728043665931">Blocați întotdeauna accesul la microfon</translation>
-<translation id="2365626167708453863">Alege un cont din Google Smart Lock</translation>
 <translation id="2367972762794486313">Afișați aplicații</translation>
 <translation id="2368075211218459617">Activați Căutarea contextuală.</translation>
 <translation id="2370882663124746154">Activează modul Pinyin dublu</translation>
@@ -2670,7 +2668,6 @@
 <translation id="4780374166989101364">Activează API-uri cu extensii experimentale. Reține că galeria de extensii nu îți permite să încarci extensii care utilizează API-uri experimentale.</translation>
 <translation id="4781787911582943401">Mărește ecranul</translation>
 <translation id="4782449893814226250">Ai întrebat părinții dacă poți accesa această pagină.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}few{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Prezentare PowerPoint</translation>
 <translation id="4785040501822872973">Acest computer se va reseta în <ph name="LOGOUT_TIME_LEFT" /> (de) secunde.
 Apăsați pe orice tastă pentru a continua explorarea.</translation>
@@ -3201,7 +3198,6 @@
 <translation id="5527474464531963247">De asemenea, puteți selecta altă rețea.</translation>
 <translation id="5527963985407842218">Declanșarea modului Cititor</translation>
 <translation id="5528368756083817449">Manager de marcaje</translation>
-<translation id="5529098031581368697">Fundalul actual este setat de „<ph name="APP_NAME" />”</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Global</translation>
 <translation id="5533555070048896610">Transliterație (namaste → नमस्ते)</translation>
@@ -3317,7 +3313,6 @@
 <translation id="5702898740348134351">&amp;Editează motoarele de căutare...</translation>
 <translation id="5703594190584829406">Afișează sugestiile de completare automată deasupra tastaturii, și nu într-o listă drop-down.</translation>
 <translation id="5704272569086782895">Activează rasterizarea cu fire de execuție la nivel de GPU.</translation>
-<translation id="570544101664452060">Notificări WebUsb experimentale.</translation>
 <translation id="5706551819490830015">Gestionați adresele de facturare...</translation>
 <translation id="5707185214361380026">Nu s-a încărcat extensia de la:</translation>
 <translation id="5707604204219538797">Cuvântul următor</translation>
@@ -3466,7 +3461,6 @@
 <translation id="5900302528761731119">Fotografie de profil Google</translation>
 <translation id="5900623698597156974">Prin revenirea la TLS 1.0, dialogul de confirmare cu serverul a fost a efectuat, dar alternativele TLS 1.0 nu mai sunt acceptate. Serverul trebuie să fie actualizat pentru a implementa corect negocierea versiunilor și, de preferință, pentru a fi compatibil cu TLS 1.2.</translation>
 <translation id="590253956165195626">Oferă traducerea paginilor care nu sunt în limba în care citesc.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{Un element}few{# elemente}other{# de elemente}}</translation>
 <translation id="5904093760909470684">Configurare proxy</translation>
 <translation id="5906065664303289925">Adresă hardware:</translation>
 <translation id="5910363049092958439">Sal&amp;vează imaginea ca...</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb
index ef567fe..ebbe6a3 100644
--- a/chrome/app/resources/generated_resources_ru.xtb
+++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Доступ к этим USB-устройствам</translation>
 <translation id="1038168778161626396">Только расшифровка</translation>
 <translation id="1038842779957582377">неизвестное имя</translation>
-<translation id="1040931876666128942">Оповещения WebUsb</translation>
 <translation id="1042174272890264476">В ваш компьютер встроена библиотека RLZ <ph name="SHORT_PRODUCT_NAME" />. RLZ присваивает компьютеру неуникальную и не позволяющую идентифицировать пользователя метку, с помощью которой мы можем оценить количество запросов и статистику использования этого продукта (<ph name="SHORT_PRODUCT_NAME" />) по результатам рекламных кампаний. Иногда метки могут включаться в поисковые запросы, сделанные в этом продукте (<ph name="PRODUCT_NAME" />).</translation>
 <translation id="1042574203789536285">От <ph name="URL" /> поступил запрос на постоянное хранение большого объема данных на вашем мобильном устройстве.</translation>
 <translation id="1045157690796831147">Транслитерация (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Новые настройки файлов cookie вступят в силу после обновления страницы.</translation>
 <translation id="14720830734893704">Включает поддержку виртуальной клавиатуры.</translation>
 <translation id="1474339897586437869">Не удалось загрузить <ph name="FILENAME" />. Не хватает пространства на Google Диске.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 пароль}one{# пароль}few{# пароля}many{# паролей}other{# пароля}}</translation>
 <translation id="1476949146811612304">Выберите <ph name="BEGIN_LINK" />поисковую систему по умолчанию<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Кеш токенов API идентификационных данных</translation>
 <translation id="1478340334823509079">Подробные сведения: <ph name="FILE_NAME" /></translation>
@@ -920,6 +918,7 @@
 <translation id="2326606747676847821">Режим инкогнито</translation>
 <translation id="2326931316514688470">Пере&amp;загрузить приложение</translation>
 <translation id="2327492829706409234">Включить приложение</translation>
+<translation id="2329597144923131178">Войдите, чтобы синхронизировать закладки, пароли, историю и т. д. на всех устройствах.</translation>
 <translation id="2332131598580221120">Открыть в Интернет-магазине</translation>
 <translation id="2332742915001411729">Масштаб по умолчанию</translation>
 <translation id="2335122562899522968">Эта страница установила файлы cookie.</translation>
@@ -943,7 +942,6 @@
 <translation id="2359808026110333948">Далее</translation>
 <translation id="236128817791440714">Рекомендуем настроить Smart Lock для Android</translation>
 <translation id="236141728043665931">Всегда блокировать доступ к микрофону</translation>
-<translation id="2365626167708453863">Выбор аккаунта для Google Smart Lock</translation>
 <translation id="2367972762794486313">Показать сервисы</translation>
 <translation id="2368075211218459617">Включить Контекстный поиск</translation>
 <translation id="2370882663124746154">Включить режим Double-Pinyin</translation>
@@ -2654,7 +2652,6 @@
 <translation id="4780374166989101364">Активирует API экспериментальных расширений. Обратите внимание, что вы не сможете выполнять загрузку в галереи расширения, где используются экспериментальные API.</translation>
 <translation id="4781787911582943401">Увеличить масштаб экрана</translation>
 <translation id="4782449893814226250">Вашим родителям отправлен запрос на просмотр страницы.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 КБ}one{# КБ}few{# КБ}many{# КБ}other{# КБ}}</translation>
 <translation id="4784330909746505604">Презентация PowerPoint</translation>
 <translation id="4785040501822872973">Компьютер перезагрузится через <ph name="LOGOUT_TIME_LEFT" /> сек.
 Чтобы продолжить работу, нажмите любую клавишу.</translation>
@@ -3185,7 +3182,6 @@
 <translation id="5527474464531963247">Можно выбрать другую сеть.</translation>
 <translation id="5527963985407842218">Активация кнопки "Режим чтения"</translation>
 <translation id="5528368756083817449">Диспетчер закладок</translation>
-<translation id="5529098031581368697">Эти обои установлены приложением <ph name="APP_NAME" /></translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Глобально</translation>
 <translation id="5533555070048896610">Транслитерация (namaste → नमस्ते)</translation>
@@ -3301,7 +3297,6 @@
 <translation id="5702898740348134351">&amp;Изменить поисковые системы...</translation>
 <translation id="5703594190584829406">Показывает варианты автозаполнения над клавиатурой, а не в раскрывающемся меню.</translation>
 <translation id="5704272569086782895">Включить аппаратную растеризацию</translation>
-<translation id="570544101664452060">Экспериментальные оповещения WebUsb.</translation>
 <translation id="5706551819490830015">Настроить платежные адреса...</translation>
 <translation id="5707185214361380026">Не удалось загрузить расширение из:</translation>
 <translation id="5707604204219538797">К следующему слову</translation>
@@ -3449,7 +3444,6 @@
 <translation id="5900302528761731119">Фотография профиля Google</translation>
 <translation id="5900623698597156974">Мы запретили подтверждение защищенного соединения с помощью отката протокола до TLS 1.0. Обновите сервер, чтобы он поддерживал протокол TLS 1.2.</translation>
 <translation id="590253956165195626">Предлагать перевод страниц, если их язык отличается от используемого в браузере.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 запись}one{# запись}few{# записи}many{# записей}other{# записи}}</translation>
 <translation id="5904093760909470684">Основные</translation>
 <translation id="5906065664303289925">Аппаратный адрес:</translation>
 <translation id="5910363049092958439">Сохранить изображение как...</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb
index a2d3902..837eb0cc 100644
--- a/chrome/app/resources/generated_resources_sk.xtb
+++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Prístup ku ktorýmkoľvek z týchto zariadení USB</translation>
 <translation id="1038168778161626396">Len zašifrovanie</translation>
 <translation id="1038842779957582377">neznámy názov</translation>
-<translation id="1040931876666128942">Upozornenia WebUsb</translation>
 <translation id="1042174272890264476">Váš počítač má tiež vstavanú knižnicu RLZ prehliadača <ph name="SHORT_PRODUCT_NAME" />. Knižnica RLZ priradí nejedinečnú značku, pomocou ktorej sa nedá zistiť totožnosť, na meranie výsledkov a použitia prehliadača <ph name="SHORT_PRODUCT_NAME" /> vyplývajúceho z konkrétnej propagačnej kampane. Tieto menovky sa niekedy zobrazujú v dopytoch Vyhľadávania Google v prehliadači <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285">Stránky <ph name="URL" /> chcú natrvalo ukladať veľké množstvo údajov vo vašom zariadení.</translation>
 <translation id="1045157690796831147">Prepis (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">Nové nastavenia súborov cookie sa použijú po obnovení stránky.</translation>
 <translation id="14720830734893704">Povolí podporu virtuálnej klávesnice.</translation>
 <translation id="1474339897586437869">Súbor <ph name="FILENAME" /> nebol nahraný. Na Disku Google nemáte dostatok voľného miesta.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 heslo}few{# heslá}many{# hesla}other{# hesiel}}</translation>
 <translation id="1476949146811612304">Nastavte, ktorý vyhľadávač sa použije pri vyhľadávaní vo <ph name="BEGIN_LINK" />všeobecnom poli<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Vyrovnávacia pamäť tokenu rozhrania Identity API</translation>
 <translation id="1478340334823509079">Podrobnosti: <ph name="FILE_NAME" /></translation>
@@ -925,6 +923,7 @@
 <translation id="2326606747676847821">Režim inkognito</translation>
 <translation id="2326931316514688470">&amp;Znova načítať aplikáciu</translation>
 <translation id="2327492829706409234">Povoliť aplikáciu</translation>
+<translation id="2329597144923131178">Prihláste sa a získajte tak svoje záložky, históriu, heslá a ďalšie nastavenia na všetkých svojich zariadeniach.</translation>
 <translation id="2332131598580221120">Zobraziť v obchode</translation>
 <translation id="2332742915001411729">Obnoviť na predvolené hodnoty</translation>
 <translation id="2335122562899522968">Táto stránka nastavila súbory cookie.</translation>
@@ -948,7 +947,6 @@
 <translation id="2359808026110333948">Pokračovať</translation>
 <translation id="236128817791440714">Odporúčané: Nastavte si funkciu Smart Lock pre Android</translation>
 <translation id="236141728043665931">Vždy blokovať prístup k mikrofónu</translation>
-<translation id="2365626167708453863">Zvoľte účet zo svojej funkcie Google Smart Lock</translation>
 <translation id="2367972762794486313">Zobraziť aplikácie</translation>
 <translation id="2368075211218459617">Aktivácia kontextového vyhľadávania.</translation>
 <translation id="2370882663124746154">Povoliť režim dvojitého vstupu pinyin</translation>
@@ -2665,7 +2663,6 @@
 <translation id="4780374166989101364">Povolí experimentálne rozhrania API rozšírení. Upozorňujeme, že do galérie rozšírení nie je povolené nahrávať rozšírenia, ktoré používajú experimentálne rozhrania API.</translation>
 <translation id="4781787911582943401">Priblížiť obrazovku</translation>
 <translation id="4782449893814226250">Požiadali ste rodičov o povolenie návštevy tejto stránky.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}few{# kB}many{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Prezentácia aplikácie PowerPoint</translation>
 <translation id="4785040501822872973">Počítač sa o <ph name="LOGOUT_TIME_LEFT" /> sekúnd reštartuje.
 Ak chcete pokračovať v práci, stlačte ľubovoľný kláves.</translation>
@@ -3196,7 +3193,6 @@
 <translation id="5527474464531963247">Môžete tiež vybrať inú sieť.</translation>
 <translation id="5527963985407842218">Aktivácia režimu čítačky</translation>
 <translation id="5528368756083817449">Správca záložiek</translation>
-<translation id="5529098031581368697">Aktuálnu tapetu nastavila aplikácia <ph name="APP_NAME" /></translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Globálne</translation>
 <translation id="5533555070048896610">Prepis (namaste → नमस्ते)</translation>
@@ -3312,7 +3308,6 @@
 <translation id="5702898740348134351">Upraviť vyhľadávaci&amp;e nástroje...</translation>
 <translation id="5703594190584829406">Zobrazí návrhy automatického dopĺňania v hornej časti klávesnice, a nie v rozbaľovacom zozname.</translation>
 <translation id="5704272569086782895">Povoliť rastrovanie prostredníctvom jednotky GPU</translation>
-<translation id="570544101664452060">Experimentálne upozornenia WebUsb</translation>
 <translation id="5706551819490830015">Správa fakturačných adries...</translation>
 <translation id="5707185214361380026">Nepodarilo sa načítať rozšírenie zo zdroja</translation>
 <translation id="5707604204219538797">Ďalšie slovo</translation>
@@ -3461,7 +3456,6 @@
 <translation id="5900302528761731119">Fotografia profilu Google</translation>
 <translation id="5900623698597156974">Záložný protokol TLS 1.0 dokázal nadviazať spojenie so serverom, ale protokoly TLS 1.0 už neakceptujeme. Server musíte aktualizovať, aby správne implementoval vyjednávanie verzie a radšej podporoval protokol TLS 1.2.</translation>
 <translation id="590253956165195626">Ponúkať preklad stránok, ktorým by ste nemuseli rozumieť.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 položka}few{# položky}many{# položky}other{# položiek}}</translation>
 <translation id="5904093760909470684">Konfigurácia servera proxy</translation>
 <translation id="5906065664303289925">Hardvérová adresa:</translation>
 <translation id="5910363049092958439">Uložiť &amp;obrázok ako...</translation>
@@ -4129,7 +4123,7 @@
 <translation id="6941937518557314510">Ak chcete vykonať overenie pre hostiteľa <ph name="HOST_NAME" /> pomocou svojho certifikátu, prihláste sa do <ph name="TOKEN_NAME" />.</translation>
 <translation id="6945221475159498467">Vybrať</translation>
 <translation id="6948142510520900350">Prístup na túto webovú stránku zablokoval váš &lt;strong&gt;správca systému&lt;/strong&gt;.</translation>
-<translation id="6948736568813450284">Pre vývojárov: použite službu karantény pre volania prostredníctvom rozhrania Google Payments API.</translation>
+<translation id="6948736568813450284">Pre vývojárov: Použite službu karantény pre volania prostredníctvom rozhrania Google Payments API.</translation>
 <translation id="6949306908218145636">Pridať otvorené stránky medzi záložky...</translation>
 <translation id="695164542422037736">Ak je táto možnosť povolená a ak je hlavná časť štylizovaná s pevne fixovaným pozadím, bude mať pozadie vlastnú zloženú vrstvu.</translation>
 <translation id="6954850746343724854">Povoliť technológiu Native client pre všetky webové aplikácie (aj tie, ktoré nie sú nainštalované z Internetového obchodu Chrome).</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb
index b0ce1b8..bc11c587 100644
--- a/chrome/app/resources/generated_resources_sl.xtb
+++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Dostop do katere koli od teh naprav USB</translation>
 <translation id="1038168778161626396">Le šifriranje</translation>
 <translation id="1038842779957582377">neznano ime</translation>
-<translation id="1040931876666128942">Obvestila WebUsb.</translation>
 <translation id="1042174272890264476">V vašem računalniku je tudi vgrajena knjižnica RLZ izdelka <ph name="SHORT_PRODUCT_NAME" />. RLZ za merjenje iskanj in uporabe izdelka <ph name="SHORT_PRODUCT_NAME" /> v okviru določene promocijske akcije dodeli neenolično oznako, ki ne omogoča osebne prepoznave. Te oznake so včasih v izdelku <ph name="PRODUCT_NAME" /> prikazane v iskalnih poizvedbah v Googlu.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> želi trajno shranjevati velike količine podatkov v vaši napravi.</translation>
 <translation id="1045157690796831147">Prečrkovanje (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Nove nastavitve za piškotke bodo začele veljati, ko znova naložite stran.</translation>
 <translation id="14720830734893704">Omogočanje podpore za virtualno tipkovnico.</translation>
 <translation id="1474339897586437869">Datoteka »<ph name="FILENAME" />« ni bila naložena. V Googlu Drive nimate dovolj razpoložljivega prostora.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 geslo}one{# geslo}two{# gesli}few{# gesla}other{# gesel}}</translation>
 <translation id="1476949146811612304">Nastavite, kateri iskalnik boste uporabljali pri iskanju v
         <ph name="BEGIN_LINK" />naslovni vrstici<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Predpomnilnik žetonov za API za identiteto</translation>
@@ -925,6 +923,7 @@
 <translation id="2326606747676847821">Brskaj brez beleženja zgodovine</translation>
 <translation id="2326931316514688470">&amp;Znova naloži aplikacijo</translation>
 <translation id="2327492829706409234">Omogoči aplikacijo</translation>
+<translation id="2329597144923131178">Prijavite se, da boste lahko dostopali do zaznamkov, zgodovine, gesel in drugih nastavitev v vseh napravah.</translation>
 <translation id="2332131598580221120">Ogled v trgovini</translation>
 <translation id="2332742915001411729">Ponastavi na privzeto</translation>
 <translation id="2335122562899522968">Ta stran je nastavila piškotke.</translation>
@@ -948,7 +947,6 @@
 <translation id="2359808026110333948">Nadaljuj</translation>
 <translation id="236128817791440714">Priporočeno: Nastavite Smart Lock za Android</translation>
 <translation id="236141728043665931">Vedno prepreči dostop do mikrofona</translation>
-<translation id="2365626167708453863">Izbira računa v storitvi Google Smart Lock</translation>
 <translation id="2367972762794486313">Pokaži aplikacije</translation>
 <translation id="2368075211218459617">Omogočanje sobesedilnega iskanja.</translation>
 <translation id="2370882663124746154">Omogoči način večglasniškega pinjina</translation>
@@ -2665,7 +2663,6 @@
 <translation id="4780374166989101364">Omogoča poskusno razširitev API-jev. Galerija razširitev ne omogoča nalaganje razširitev, ki uporabljajo poskusne API-je.</translation>
 <translation id="4781787911582943401">Povečava zaslona</translation>
 <translation id="4782449893814226250">Starše si vprašal, ali smeš obiskati to stran.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}one{# KB}two{# KB}few{# KB}other{# KB}}</translation>
 <translation id="4784330909746505604">PowerPointova predstavitev</translation>
 <translation id="4785040501822872973">Računalnik se bo ponastavil čez <ph name="LOGOUT_TIME_LEFT" /> s.
 Pritisnite katero koli tipko, če želite še naprej raziskovati.</translation>
@@ -3196,7 +3193,6 @@
 <translation id="5527474464531963247">Izberete lahko tudi drugo omrežje.</translation>
 <translation id="5527963985407842218">Sprožitev načina bralnika</translation>
 <translation id="5528368756083817449">Upravitelj zaznamkov</translation>
-<translation id="5529098031581368697">Trenutno ozadje je nastavila aplikacija »<ph name="APP_NAME" />«</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Globalno</translation>
 <translation id="5533555070048896610">Prečrkovanje (namaste → नमस्ते)</translation>
@@ -3313,7 +3309,6 @@
 <translation id="5702898740348134351">&amp;Urejanje iskalnikov ...</translation>
 <translation id="5703594190584829406">Pokaže predloge samodejnega izpolnjevanja na vrhu tipkovnice, ne v spustnem meniju.</translation>
 <translation id="5704272569086782895">Omogočanje nitne rasterizacije z GPE.</translation>
-<translation id="570544101664452060">Poskusna obvestila WebUsb.</translation>
 <translation id="5706551819490830015">Upravljanje naslovov za izstavitev računa ...</translation>
 <translation id="5707185214361380026">Ni bilo mogoče naložiti razširitve z mesta:</translation>
 <translation id="5707604204219538797">Naslednja beseda</translation>
@@ -3462,7 +3457,6 @@
 <translation id="5900302528761731119">Fotografija profila Google</translation>
 <translation id="5900623698597156974">Preklop na TLS 1.0 je omogočil začetek povezave s strežnikom, vendar preklopa na TLS 1.0 ne podpiramo več. Strežnik je treba posodobiti, da bo pravilno izvedel pogajanja glede različice in podpiral TLS 1.2, če je mogoče.</translation>
 <translation id="590253956165195626">Ponudi prevajanje strani, ki niso v vašem jeziku.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 element}one{# element}two{# elementa}few{# elementi}other{# elementov}}</translation>
 <translation id="5904093760909470684">Konfiguracija strežnika proxy</translation>
 <translation id="5906065664303289925">Naslov strojne opreme:</translation>
 <translation id="5910363049092958439">Sh&amp;rani sliko kot ...</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb
index 231a95e..2bf83c3f 100644
--- a/chrome/app/resources/generated_resources_sr.xtb
+++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Приступ било ком од ових USB уређаја</translation>
 <translation id="1038168778161626396">Само шифруј</translation>
 <translation id="1038842779957582377">непознато име</translation>
-<translation id="1040931876666128942">WebUsb обавештења.</translation>
 <translation id="1042174272890264476">Уз рачунар такође добијате уграђену RLZ библиотеку производа <ph name="SHORT_PRODUCT_NAME" />. RLZ додељује нејединствену ознаку помоћу које вас није могуће лично идентификовати да би измерио претраге и коришћење производа <ph name="SHORT_PRODUCT_NAME" /> који су подстакнути одређеном промотивном кампањом. Те ознаке се понекад приказују у упитима Google претраге у производу <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> жели трајно да складишти велике количине података на уређају.</translation>
 <translation id="1045157690796831147">Транслитерација (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Ново подешавање колачића биће примењено након поновног учитавања странице.</translation>
 <translation id="14720830734893704">Омогућите подршку за виртуелну тастатуру.</translation>
 <translation id="1474339897586437869">Датотека „<ph name="FILENAME" />“ није отпремљена. Није било довољно слободног места на Google диску.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 лозинка}one{# лозинка}few{# лозинке}other{# лозинки}}</translation>
 <translation id="1476949146811612304">Подесите претраживач који ће се користити када претражујете из <ph name="BEGIN_LINK" />омнибокса<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Кеш токена API-ја за идентитет</translation>
 <translation id="1478340334823509079">Детаљи: <ph name="FILE_NAME" /></translation>
@@ -923,6 +921,7 @@
 <translation id="2326606747676847821">Пређи у режим без архивирања</translation>
 <translation id="2326931316514688470">&amp;Поново учитај апликацију</translation>
 <translation id="2327492829706409234">Омогући апликацију</translation>
+<translation id="2329597144923131178">Пријавите се да би вам обележивачи, историја, лозинке и друга подешавања били доступни на свим уређајима.</translation>
 <translation id="2332131598580221120">Прикажи у продавници</translation>
 <translation id="2332742915001411729">Врати на подразумевану вредност</translation>
 <translation id="2335122562899522968">Ова страница поставља колачиће.</translation>
@@ -946,7 +945,6 @@
 <translation id="2359808026110333948">Настави</translation>
 <translation id="236128817791440714">Препоручено: Подесите Smart Lock за Android</translation>
 <translation id="236141728043665931">Увек блокирај приступ микрофону</translation>
-<translation id="2365626167708453863">Изаберите налог из Google Smart Lock-а</translation>
 <translation id="2367972762794486313">Прикажите апликације</translation>
 <translation id="2368075211218459617">Омогући Контекстуалну претрагу.</translation>
 <translation id="2370882663124746154">Омогући Double-Pinyin режим</translation>
@@ -2662,7 +2660,6 @@
 <translation id="4780374166989101364">Омогућава експерименталне API-је додатка. Имајте на уму да галерија додатака не дозвољава да отпремате додатке који користе експерименталне API-је.</translation>
 <translation id="4781787911582943401">Увећавање екрана</translation>
 <translation id="4782449893814226250">Питао/ла си родитеље да ли смеш да посетиш ову страницу.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}one{# kB}few{# kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint презентација</translation>
 <translation id="4785040501822872973">Овај рачунар ће се поново покренути за <ph name="LOGOUT_TIME_LEFT" /> секунда.
 Притисните било који тастер да бисте наставили да истражујете.</translation>
@@ -3193,7 +3190,6 @@
 <translation id="5527474464531963247">Можете и да изаберете неку другу мрежу.</translation>
 <translation id="5527963985407842218">Покретање Режима читаоца</translation>
 <translation id="5528368756083817449">Менаџер обележивача</translation>
-<translation id="5529098031581368697">Актуелну позадину подешава „<ph name="APP_NAME" />“</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Опште</translation>
 <translation id="5533555070048896610">Транслитерација (namaste → नमस्ते)</translation>
@@ -3311,7 +3307,6 @@
 <translation id="5702898740348134351">&amp;Измени претраживаче...</translation>
 <translation id="5703594190584829406">Приказује предлоге за Аутоматско попуњавање изнад тастатуре уместо у падајућем менију.</translation>
 <translation id="5704272569086782895">Омогући GPU растеризацију са нитима.</translation>
-<translation id="570544101664452060">Експериментална WebUsb обавештења.</translation>
 <translation id="5706551819490830015">Управљај адресама за обрачун...</translation>
 <translation id="5707185214361380026">Није успело учитавање додатка из:</translation>
 <translation id="5707604204219538797">Следећа реч</translation>
@@ -3459,7 +3454,6 @@
 <translation id="5900302528761731119">Слика Google профила</translation>
 <translation id="5900623698597156974">Резервни TLS протокол верзије 1.0 је успео да потврди спремност за пренос података на серверу, али више не прихватамо резервне TLS протоколе верзије 1.0. Сервер мора да буде ажуриран тако да исправно примени прилагођавање верзије, а пожељно би било да подржава TLS верзију 1.2.</translation>
 <translation id="590253956165195626">Нуди превод страница које нису на језику који читам.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 ставка}one{# ставка}few{# ставке}other{# ставки}}</translation>
 <translation id="5904093760909470684">Конфигурација проксија</translation>
 <translation id="5906065664303289925">Хардверска адреса:</translation>
 <translation id="5910363049092958439">Са&amp;чувај слику као...</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb
index 339685c67..2b384f7 100644
--- a/chrome/app/resources/generated_resources_sv.xtb
+++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Komma åt någon av dessa USB-enheter</translation>
 <translation id="1038168778161626396">Endast chiffrering</translation>
 <translation id="1038842779957582377">okänt namn</translation>
-<translation id="1040931876666128942">WebUsb-aviseringar.</translation>
 <translation id="1042174272890264476">Datorn har även RLZ-biblioteket för <ph name="SHORT_PRODUCT_NAME" /> inbyggt. RLZ tilldelar en icke-unik, icke-personligt identifierbar tagg för att mäta antalet sökningar och användningen av <ph name="SHORT_PRODUCT_NAME" /> som drivs av en viss reklamkampanj. Dessa etiketter visas ibland vid sökningar på Google i <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> vill lagra stora mängder data på din enhet.</translation>
 <translation id="1045157690796831147">Translitterering (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">De nya cookie-inställningarna börjar gälla när sidan uppdateras.</translation>
 <translation id="14720830734893704">Aktivera stöd för virtuellt tangentbord.</translation>
 <translation id="1474339897586437869"><ph name="FILENAME" /> laddades inte upp. Det fanns inte tillräckligt mycket ledigt utrymme på Google Drive.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 lösenord}other{# lösenord}}</translation>
 <translation id="1476949146811612304">Ange vilken sökmotor som används när du söker från <ph name="BEGIN_LINK" />adressfältet<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Tokencacheminne för identitets-API</translation>
 <translation id="1478340334823509079">Detaljer: <ph name="FILE_NAME" /></translation>
@@ -923,6 +921,7 @@
 <translation id="2326606747676847821">Surfa inkognito</translation>
 <translation id="2326931316514688470">&amp;Läs in appen igen</translation>
 <translation id="2327492829706409234">Aktivera app</translation>
+<translation id="2329597144923131178">Logga in så blir bokmärken, historik, lösenord med mera tillgängligt på alla dina enheter.</translation>
 <translation id="2332131598580221120">Visa i butik</translation>
 <translation id="2332742915001411729">Återställ standardvärden</translation>
 <translation id="2335122562899522968">Den här sidan angav cookies.</translation>
@@ -946,7 +945,6 @@
 <translation id="2359808026110333948">Fortsätt</translation>
 <translation id="236128817791440714">Rekommenderas: Konfigurera Smart Lock för Android</translation>
 <translation id="236141728043665931">Blockera alltid mikrofonåtkomsten</translation>
-<translation id="2365626167708453863">Välj ett konto från Google Smart Lock</translation>
 <translation id="2367972762794486313">Visa appar</translation>
 <translation id="2368075211218459617">Aktivera kontextsökning.</translation>
 <translation id="2370882663124746154">Aktivera Double-Pinyin-läge</translation>
@@ -2666,7 +2664,6 @@
 <translation id="4780374166989101364">Aktiverar tillägg med experimentella programmeringsgränssnitt. Observera att tilläggsgalleriet inte tillåter att du laddar upp tillägg med experimentella programmeringsgränssnitt.</translation>
 <translation id="4781787911582943401">Zooma in skärmen</translation>
 <translation id="4782449893814226250">Du har frågat dina föräldrar om lov att besöka den här sidan.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint-presentation</translation>
 <translation id="4785040501822872973">Den här datorn återställs om <ph name="LOGOUT_TIME_LEFT" /> sekunder.
 Tryck på någon tangent om du vill fortsätta utforska.</translation>
@@ -3197,7 +3194,6 @@
 <translation id="5527474464531963247">Du kan också välja ett annat nätverk.</translation>
 <translation id="5527963985407842218">Utlöser läsläget</translation>
 <translation id="5528368756083817449">Bokmärkshanteraren</translation>
-<translation id="5529098031581368697">Den aktuella bakgrunden har angetts av <ph name="APP_NAME" /></translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Globalt</translation>
 <translation id="5533555070048896610">Translitterering (namaste → नमस्ते)</translation>
@@ -3313,7 +3309,6 @@
 <translation id="5702898740348134351">&amp;Redigera sökmotorer...</translation>
 <translation id="5703594190584829406">Visar förslag från Autofyll ovanför tangentbordet i stället för i en rullgardinsmeny.</translation>
 <translation id="5704272569086782895">Aktivera trådad GPU-rastrering.</translation>
-<translation id="570544101664452060">Experiment med WebUsb-aviseringar.</translation>
 <translation id="5706551819490830015">Hantera faktureringsadresser ...</translation>
 <translation id="5707185214361380026">Det gick inte att läsa in tillägget från:</translation>
 <translation id="5707604204219538797">Nästa ord</translation>
@@ -3462,7 +3457,6 @@
 <translation id="5900302528761731119">Profilfoto i Google Profiler</translation>
 <translation id="5900623698597156974">Ett alternativ för TLS 1.0 kunde utföra en handskakning med servern, men vi godkänner inte längre alternativ för TLS 1.0. Servern måste uppdateras så att den korrekt implementerar versionsförhandling och helst har stöd för TLS 1.2.</translation>
 <translation id="590253956165195626">Erbjud att översätta sidor som inte är på ett språk du kan läsa.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 objekt}other{# objekt}}</translation>
 <translation id="5904093760909470684">Proxykonfiguration</translation>
 <translation id="5906065664303289925">Maskinvaruadress:</translation>
 <translation id="5910363049092958439">S&amp;para bild som...</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb
index 3ae27355..4080ef9 100644
--- a/chrome/app/resources/generated_resources_sw.xtb
+++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Fikia chochote kati ya vifaa hivi vya USB</translation>
 <translation id="1038168778161626396">Usimabji Tu</translation>
 <translation id="1038842779957582377">jina lisilojulikana</translation>
-<translation id="1040931876666128942">Arifa za WebUsb.</translation>
 <translation id="1042174272890264476">Kompyuta yako pia huja na maktaba ya <ph name="SHORT_PRODUCT_NAME" /> ya RLZ iliyojengewa ndani. RLZ hutoa lebo isiyo ya kipekee, isiyotambulika kibinafsi ili kupima utafutaji na matumizi ya <ph name="SHORT_PRODUCT_NAME" />  yanayoendeshwa na kampeni husika ya ukwezaji. Lebo hizi wakati mwingine hutokea katika hoja za Huduma ya Tafuta na Google katika <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> inataka kuhifadhi data kubwa kwenye kifaa chako daima.</translation>
 <translation id="1045157690796831147">Unukuzi wa mfumo wa kuandika (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Mipangilio mipya ya kidakuzi itaanza kutumika baada ya kupakia upya ukurasa.</translation>
 <translation id="14720830734893704">Washa utumiaji wa kibodi isiyo bayana.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" haikupakiwa. Hakuna nafasi ya kutosha katika Hifadhi yako ya Google.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{Nenosiri 1}other{Manenosiri #}}</translation>
 <translation id="1476949146811612304">Bainisha ni mtambo upi wa kutafuta unaotumika wakati wa kutafuta kutoka
         <ph name="BEGIN_LINK" />Sanduku Kuu<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Akiba ya Kitambulisho cha Tokeni ya API</translation>
@@ -778,7 +776,7 @@
 <translation id="2135787500304447609">&amp;Endelea</translation>
 <translation id="2136953289241069843">Unukuzi wa mfumo wa kuandika (namaste → नमस्कार)</translation>
 <translation id="2137808486242513288">Ongeza mtumiaji</translation>
-<translation id="2142328300403846845">Fungua Kiungo kama</translation>
+<translation id="2142328300403846845">Fungua Kiungo ukitumia</translation>
 <translation id="214353449635805613">Piga picha ya skrini ya eneo</translation>
 <translation id="2143778271340628265">Usanidi wa proksi na mtumiaji</translation>
 <translation id="2143915448548023856">Onyesha mipangilio</translation>
@@ -922,6 +920,7 @@
 <translation id="2326606747676847821">Vinjari katika Hali Fiche</translation>
 <translation id="2326931316514688470">Pakia upya programu</translation>
 <translation id="2327492829706409234">Washa programu</translation>
+<translation id="2329597144923131178">Ingia katika akaunti ili upate alamisho, historia, manenosiri, na mipangilio yako mingine kwenye vifaa vyako vyote.</translation>
 <translation id="2332131598580221120">Angalia katika Duka la Wavuti</translation>
 <translation id="2332742915001411729">Rejesha kwenye chaguo-msingi</translation>
 <translation id="2335122562899522968">Ukurasa huu unaweka vidakuzi.</translation>
@@ -945,7 +944,6 @@
 <translation id="2359808026110333948">Endelea</translation>
 <translation id="236128817791440714">Inapendekezwa: Weka Smart Lock ya Android</translation>
 <translation id="236141728043665931">Zuia ufikiaji wa maikrofoni kila wakati</translation>
-<translation id="2365626167708453863">Chagua akaunti kutoka kwenye Google Smart Lock yako</translation>
 <translation id="2367972762794486313">Onyesha programu</translation>
 <translation id="2368075211218459617">Washa Kutafuta katika Muktadha</translation>
 <translation id="2370882663124746154">Wezesha modi ya Pinyin Maradufu</translation>
@@ -1045,7 +1043,7 @@
 <translation id="2501173422421700905">Cheti Kimesimamishwa</translation>
 <translation id="2501278716633472235">Rudi nyuma</translation>
 <translation id="2501797496290880632">Charaza mkato</translation>
-<translation id="2502441965851148920">Sasisho za kiotomatiki zimewashwa. Sasisho za kujifanyia zimezimwa na msimamizi wako.</translation>
+<translation id="2502441965851148920">Sasisho za kiotomatiki zimewashwa. Sasisho za kujiwekea zimezimwa na msimamizi wako.</translation>
 <translation id="2504775205691825589">Huenda seva inayopangisha ukurasa huo wa wavuti imejaa au inakarabatiwa.
         Ili uepuke kuwa na maelezo mengi na kuharibu hali zaidi,
        maombi yanayotumwa kwenye URL hii yamesimamishwa kwa muda.</translation>
@@ -1521,7 +1519,7 @@
 <translation id="3140353188828248647">Lenga upau anwani</translation>
 <translation id="3144126448740580210">IMEKAMILIKA</translation>
 <translation id="3144135466825225871">Imeshindwa kubadilisha faili ya crx. Angalia kuona ikiwa faili inatumika.</translation>
-<translation id="3144647712221361880">Fungua kiungo kama</translation>
+<translation id="3144647712221361880">Fungua kiungo ukitumia</translation>
 <translation id="31454997771848827">Vikoa vya kikundi</translation>
 <translation id="3147485256806412701">Tovuti hii inatumia kikoa kipya cha ngazi ya juu.</translation>
 <translation id="3149510190863420837">Programu za Chrome</translation>
@@ -2648,7 +2646,6 @@
 <translation id="4780374166989101364">Inawezesha APl za kiendelezi cha majaribio. Kumbuka kwamba ghala la kiendelezi halikuruhusu kupakia viendelezi vinavyotumia APl za majaribio.</translation>
 <translation id="4781787911582943401">Kuza katika skrini</translation>
 <translation id="4782449893814226250">Uliwauliza wazazi wako ikiwa ni sawa kuutembelea ukurasa huu.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{kB 1}other{kB #}}</translation>
 <translation id="4784330909746505604">Wasilisho la PowerPoint</translation>
 <translation id="4785040501822872973">Kompyuta hii itaweka upya katika sekunde <ph name="LOGOUT_TIME_LEFT" />. Bonyeza kitufe chochote ili kuendelea kuchunguza.</translation>
 <translation id="4786993863723020412">Hitilafu ya kusoma akiba</translation>
@@ -3178,7 +3175,6 @@
 <translation id="5527474464531963247">Unaweza pia kuchagua mtandao mwingine.</translation>
 <translation id="5527963985407842218">Kuanzisha Hali ya Kusoma</translation>
 <translation id="5528368756083817449">Kidhibiti Alamisho</translation>
-<translation id="5529098031581368697">Mandhari ya sasa yamewekwa na '<ph name="APP_NAME" />'</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Ulimwenguni</translation>
 <translation id="5533555070048896610">Unukuzi wa mfumo wa kuandika (namaste → नमस्ते)</translation>
@@ -3294,7 +3290,6 @@
 <translation id="5702898740348134351">&amp;Badilisha Mitambo ya Kutafuta...</translation>
 <translation id="5703594190584829406">Huonyesha mapendekezo ya Kujaza Kiotomatiki juu ya kibodi badala ya ndani ya menyu kunjuzi.</translation>
 <translation id="5704272569086782895">Washa uwekaji wa safu za picha wa GPU ulio na maelezo.</translation>
-<translation id="570544101664452060">Arifa za majaribio za WebUsb.</translation>
 <translation id="5706551819490830015">Dhibiti anwani za utozaji...</translation>
 <translation id="5707185214361380026">Haijafaulu kupakia kiendelezi kutoka:</translation>
 <translation id="5707604204219538797">Neno lifuatalo</translation>
@@ -3442,7 +3437,6 @@
 <translation id="5900302528761731119">Picha ya Wasifu katika Google</translation>
 <translation id="5900623698597156974">Hifadhi rudufu ya TLS 1.0 iliweza kukubaliana na seva, lakini hatukubali hifadhi rudufu za TLS 1.0 tena. Seva inahitaji kusasishwa ili kutekeleza kwa usahihi majadiliano ya toleo na ikiwezekana kutumia TLS 1.2.</translation>
 <translation id="590253956165195626">Toleo la kutafsiri kurasa ambazo ziko katika lugha usiyoisoma.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{Kipengee 1}other{Vipengee #}}</translation>
 <translation id="5904093760909470684">Usanidi wa Proksi</translation>
 <translation id="5906065664303289925">Anwani ya maunzi:</translation>
 <translation id="5910363049092958439">&amp;Hifadhi Picha Kama...</translation>
@@ -3939,7 +3933,7 @@
 <translation id="666541661050183336">Hupunguza kipaumbele cha kupakia rasilimali za iframe.</translation>
 <translation id="6666647326143344290">kwa Akaunti Google yako.</translation>
 <translation id="6667102209320924827">Zima upimaji wa rangi kwenye skrini yako.</translation>
-<translation id="6675665718701918026">Kifaa cha kuonyesha kimeunganishwa</translation>
+<translation id="6675665718701918026">Kifaa cha kuonyeshea kimeunganishwa</translation>
 <translation id="6677037229676347494">Kitambulisho kinachotarajiwa "<ph name="EXPECTED_ID" />", Kitambulisho kilichoko "<ph name="NEW_ID" />".</translation>
 <translation id="6680028776254050810">Badili Watumiaji</translation>
 <translation id="6681668084120808868">Piga picha</translation>
@@ -4076,7 +4070,7 @@
 <translation id="6880587130513028875">Picha zimezuiwa kwenye ukurasa huu.</translation>
 <translation id="6883209331334683549">Usaidizi wa <ph name="PRODUCT_NAME" /></translation>
 <translation id="6886871292305414135">Fungua kiungo katika &amp;kichupo kipya</translation>
-<translation id="6892812721183419409">Fungua Kiungo kama <ph name="USER" /></translation>
+<translation id="6892812721183419409">Fungua Kiungo ukitumia <ph name="USER" /></translation>
 <translation id="6896758677409633944">Nakili</translation>
 <translation id="6898440773573063262">Programu za skrini nzima sasa zinaweza kusanidiwa ili zijifungue kiotomatiki kwenye kifaa hiki.</translation>
 <translation id="6898699227549475383">Shirika (O)</translation>
@@ -4709,7 +4703,7 @@
 <translation id="7800304661137206267">Muunganisho umesimbwa fiche kwa kutumia <ph name="CIPHER" />, kwa <ph name="MAC" /> ya uthibitishaji wa ujumbe na <ph name="KX" /> kama utaratibu muhimu wa ubadilishanaji.</translation>
 <translation id="7800518121066352902">Zungusha Kinyume saa</translation>
 <translation id="7801746894267596941">Mtu aliye na kaulisiri yako tu ndiye anayeweza kusoma data yako iliyosimbwa kwa njia fiche. Kaulisiri haitumwi au kuhifadhiwa na Google. Ukisahau kaulisiri yako, utaihitaji ku</translation>
-<translation id="780301667611848630">La, asante</translation>
+<translation id="780301667611848630">Sitaki</translation>
 <translation id="7805768142964895445">Hali</translation>
 <translation id="7806513705704909664">Washa kipengele cha Kujaza Kiotomatiki ili kujaza fomu za wavuti kwa mbofyo mmoja.</translation>
 <translation id="7807711621188256451">Ruhusu <ph name="HOST" /> kufikia kamera yako kila wakati</translation>
@@ -5658,7 +5652,7 @@
 <translation id="9137013805542155359">Onyesha asili</translation>
 <translation id="9137356749601179867">Onyesha kisanduku cha kuteua ili kutoa hifadhi ya karibu ya kadi ya malipo iliyopakuliwa kutoka kwenye seva.</translation>
 <translation id="913758436357682283">Kibodi ya Myanmar Myansan</translation>
-<translation id="9137916601698928395">Fungua kiungo kama <ph name="USER" /></translation>
+<translation id="9137916601698928395">Fungua kiungo ukitumia <ph name="USER" /></translation>
 <translation id="914566504855049417">Washa majadiliano na DTLS 1.2 ya WebRTC.</translation>
 <translation id="9147392381910171771">&amp;Chaguo</translation>
 <translation id="9148058034647219655">Ondoka</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb
index 57ae98a..cf5795e 100644
--- a/chrome/app/resources/generated_resources_ta.xtb
+++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">இந்த USB சாதனங்கள் எதையும் அணுகலாம்</translation>
 <translation id="1038168778161626396">என்சைபர் மட்டுமே</translation>
 <translation id="1038842779957582377">அறியப்படாத பெயர்</translation>
-<translation id="1040931876666128942">WebUsb அறிவிப்புகள்.</translation>
 <translation id="1042174272890264476">உள்ளிணைந்த <ph name="SHORT_PRODUCT_NAME" /> இன் RLZ நூலகமும் உங்கள் கணினியில் அமைந்துள்ளது. தேடல்களையும், குறிப்பிட்ட விளம்பரப் பிரச்சாரத்தால் இயக்கப்படும் <ph name="SHORT_PRODUCT_NAME" /> இன் பயன்பாட்டையும் அளவிட தனிப்பட்டது அல்லாத, தனிப்பட்ட முறையில் அடையாளம் காண முடியாத குறியை RLZ ஒதுக்கும். சில சமயங்களில் இந்த லேபிள்கள் <ph name="PRODUCT_NAME" /> இன் Google தேடல் வினவல்களில் தோன்றும்.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> உங்கள் சாதனத்தில் அதிக அளவு தரவை நிரந்தரமாக சேமிக்க விரும்புகிறது.</translation>
 <translation id="1045157690796831147">ஒலிபெயர்ப்பு (namaskar → നമസ്കാരം)</translation>
@@ -327,7 +326,6 @@
 <translation id="1470719357688513792">பக்கத்தை மறுஏற்றம் செய்ததும் புதிய குக்கீ அமைப்புகள் செயல்படும்.</translation>
 <translation id="14720830734893704">விர்ச்சுவல் விசைப்பலகை ஆதரவை இயக்கு.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" ஏற்றப்படவில்லை. உங்கள் Google இயக்ககத்தில் போதுமான காலியிடம் இல்லை.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{ஒரு கடவுச்சொல்}other{# கடவுச்சொற்கள்}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />சர்வபுலத்திலிருந்து<ph name="END_LINK" /> தேடும் போது பயன்படுத்தப்படும் தேடு பொறியை அமைக்கலாம்.</translation>
 <translation id="1477301030751268706">அடையாள API இன் டோக்கன் தேக்ககம்</translation>
 <translation id="1478340334823509079">விவரங்கள்: <ph name="FILE_NAME" /></translation>
@@ -924,6 +922,7 @@
 <translation id="2326606747676847821">மறைநிலைக்குச் செல்</translation>
 <translation id="2326931316514688470">&amp;பயன்பாட்டை மீண்டும் ஏற்று</translation>
 <translation id="2327492829706409234">பயன்பாட்டை இயக்கு</translation>
+<translation id="2329597144923131178">உங்கள் எல்லா சாதனங்களிலும் புத்தகக்குறிகள், வரலாறு, கடவுச்சொற்கள் மற்றும் பிற அமைப்புகளைப் பெற உள்நுழையவும்.</translation>
 <translation id="2332131598580221120">அங்காடியில் காட்டு</translation>
 <translation id="2332742915001411729">இயல்புநிலைக்கு மீட்டமை</translation>
 <translation id="2335122562899522968">இந்தப் பக்கம் குக்கீகளை அமைக்கும்.</translation>
@@ -947,7 +946,6 @@
 <translation id="2359808026110333948">தொடர்க</translation>
 <translation id="236128817791440714">பரிந்துரைக்கப்பட்டது: Androidக்கான Smart Lock</translation>
 <translation id="236141728043665931">மைக்ரோஃபோன் அணுகலை எப்போதும் தடு</translation>
-<translation id="2365626167708453863">உங்கள் Google Smart Lock இலிருந்து கணக்கைத் தேர்ந்தெடுக்கவும்</translation>
 <translation id="2367972762794486313">பயன்பாடுகளைக் காட்டு</translation>
 <translation id="2368075211218459617">சூழ்நிலைக்கேற்ற தேடலை இயக்கு.</translation>
 <translation id="2370882663124746154">இரட்டைப்-பின்யின் பயன்முறையை இயக்கு</translation>
@@ -2651,7 +2649,6 @@
 <translation id="4780374166989101364">பரிசோதனை நீட்டிப்பு APIகளை இயக்குகிறது. பரிசோதனை APIகளைப் பயன்படுத்தும் நீட்டிப்புகளைப் பதிவேற்ற, நீட்டிப்பு கேலரி அனுமதிக்காது என்பதை நினைவில் கொள்க.</translation>
 <translation id="4781787911582943401">திரையைப் பெரிதாக்கவும்</translation>
 <translation id="4782449893814226250">இந்தப் பக்கத்தைப் பார்வையிடலாமா என, நீங்கள் பெற்றோர்களிடம் கேட்டுள்ளீர்கள்.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 கி.பை.}other{# கி.பை.}}</translation>
 <translation id="4784330909746505604">PowerPoint விளக்கக்காட்சி</translation>
 <translation id="4785040501822872973">இந்த கணினி <ph name="LOGOUT_TIME_LEFT" /> வினாடிகளில் மீட்டமைக்கப்படும்.
 ஆய்வுகளைத் தொடர எந்த விசையையாவது அழுத்தவும்.</translation>
@@ -3180,7 +3177,6 @@
 <translation id="5527474464531963247">நீங்கள் மற்றொரு பிணையத்தையும் தேர்வு செய்யலாம்.</translation>
 <translation id="5527963985407842218">படித்தல் பயன்முறை தூண்டல்</translation>
 <translation id="5528368756083817449">புக்மார்க் நிர்வாகி</translation>
-<translation id="5529098031581368697">நடப்பு வால்பேப்பர் '<ph name="APP_NAME" />' மூலம் அமைக்கப்பட்டது</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">முழுமைக்கும்</translation>
 <translation id="5533555070048896610">ஒலிபெயர்ப்பு (namaste → नमस्ते)</translation>
@@ -3296,7 +3292,6 @@
 <translation id="5702898740348134351">தேடுபொறிகளைத் &amp;திருத்து...</translation>
 <translation id="5703594190584829406">தன்னிரப்பி பரிந்துரைகளை கீழ்தோன்றும் பட்டியலுக்கு பதிலாக விசைப்பலகையின் மேலே காட்டும்.</translation>
 <translation id="5704272569086782895">தொடரிழை GPU ராஸ்டர் செயலாக்கத்தை இயக்கவும்.</translation>
-<translation id="570544101664452060">பரிசோதனைக்குரிய WebUsb அறிவிப்புகள்.</translation>
 <translation id="5706551819490830015">பில்லிங் முகவரிகளை நிர்வகி...</translation>
 <translation id="5707185214361380026">இதிலிருந்து நீட்டிப்பை ஏற்றுவதில் தோல்வி:</translation>
 <translation id="5707604204219538797">அடுத்த சொல்</translation>
@@ -3442,7 +3437,6 @@
 <translation id="5900302528761731119">Google சுயவிவரப் புகைப்படம்</translation>
 <translation id="5900623698597156974">TLS 1.0 க்கு மாறுவதால் சேவையகத்துடன் தகவல் பரிமாறிக்கொள்ள முடியும், ஆனால் நாங்கள் இப்போது TLS 1.0 க்கு மாறுவதை ஆதரிப்பதில்லை. பதிப்பு தகவல் மாற்றங்க்களைச் சரியாக நடைமுறைப்படுத்த சேவையகம் புதுப்பிக்கப்பட வேண்டும், மேலும் அது TLS 1.2 ஐ ஆதரிப்பதும் நன்று.</translation>
 <translation id="590253956165195626">நான் படிக்கும் மொழியில் இல்லாத பக்கங்களை மொழிபெயர்க்கச் செய்.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 உருப்படி}other{# உருப்படிகள்}}</translation>
 <translation id="5904093760909470684">ப்ராக்ஸி உள்ளமைவு</translation>
 <translation id="5906065664303289925">வன்பொருள் முகவரி:</translation>
 <translation id="5910363049092958439">படத்தை இவ்வாறு சே&amp;மி...</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb
index 17a96ab..b3f8c54 100644
--- a/chrome/app/resources/generated_resources_te.xtb
+++ b/chrome/app/resources/generated_resources_te.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">ఈ USB పరికరాల్లో వేటికైనా ప్రాప్యత</translation>
 <translation id="1038168778161626396">కోడ్ మాత్రమే</translation>
 <translation id="1038842779957582377">తెలియని పేరు</translation>
-<translation id="1040931876666128942">WebUsb నోటిఫికేషన్‌లు.</translation>
 <translation id="1042174272890264476">మీ కంప్యూటర్‌‍లో కూడా <ph name="SHORT_PRODUCT_NAME" /> యొక్క అంతర్నిర్మిత RLZ లైబ్రరీ ఉంటుంది. RLZ శోధనలను మరియు నిర్దిష్ట ప్రమోషనల్ ప్రచారం ద్వారా ఉపయోగించబడిన <ph name="SHORT_PRODUCT_NAME" /> వినియోగాన్ని లెక్కించడానికి ప్రత్యేకం కాని, వ్యక్తిగతంగా గుర్తించలేని ట్యాగ్‌ను సమర్పిస్తుంది. ఈ లేబుల్‌లు కొన్నిసార్లు <ph name="PRODUCT_NAME" />లోని Google శోధన ప్రశ్నల్లో కనిపిస్తాయి.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> శాశ్వతంగా అధిక డేటాను మీ పరికరంలో నిల్వ చేయాలనుకుంటోంది.</translation>
 <translation id="1045157690796831147">లిప్యంతరీకరణ (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">పేజీ లోడ్ అయిన తర్వాత క్రొత్త కుకీ సెట్టింగ్‌లు ప్రభావం చూపుతాయి.</translation>
 <translation id="14720830734893704">వర్చువల్ కీబోర్డ్ మద్దతును ప్రారంభించండి.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" అప్‌లోడ్ కాలేదు. మీ Google డిస్క్‌లో తగినంత ఖాళీ స్థలం లేదు.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 పాస్‌వర్డ్}other{# పాస్‌వర్డ్‌లు}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />ఓమ్నిపెట్టె<ph name="END_LINK" /> నుండి శోధించినప్పుడు ఉపయోగించవల్సిన శోధన ఇంజిన్‌ను సెట్ చేయండి.</translation>
 <translation id="1477301030751268706">గుర్తింపు API టోకెన్ కాష్</translation>
 <translation id="1478340334823509079">వివరాలు: <ph name="FILE_NAME" /></translation>
@@ -928,6 +926,7 @@
 <translation id="2326606747676847821">అజ్ఞాతంలోకి వెళ్లు</translation>
 <translation id="2326931316514688470">అనువర్తనాన్ని &amp;మళ్లీ లోడ్ చేయి</translation>
 <translation id="2327492829706409234">అనువర్తనాన్ని ప్రారంభించు</translation>
+<translation id="2329597144923131178">మీ బుక్‌మార్క్‌లు, చరిత్ర, పాస్‌వర్డ్‌లు, ఇతర సెట్టింగ్‌లను మీ అన్ని పరికరాల్లో పొందడానికి సైన్ ఇన్ చేయండి.</translation>
 <translation id="2332131598580221120">స్టోర్‌లో వీక్షించండి</translation>
 <translation id="2332742915001411729">డిఫాల్ట్‌కు రీసెట్ చేయి</translation>
 <translation id="2335122562899522968">ఈ పేజీ కుక్కీలను సెట్ చేస్తుంది.</translation>
@@ -951,7 +950,6 @@
 <translation id="2359808026110333948">కొనసాగు</translation>
 <translation id="236128817791440714">సిఫార్సు చేయబడింది: Android కోసం Smart Lockను సెటప్ చేయండి</translation>
 <translation id="236141728043665931">ఎల్లప్పుడూ మైక్రోఫోన్ ప్రాప్యతను బ్లాక్ చేయి</translation>
-<translation id="2365626167708453863">మీ Google Smart Lock నుండి ఖాతాను ఎంచుకోండి</translation>
 <translation id="2367972762794486313">అనువర్తనాలను చూపు</translation>
 <translation id="2368075211218459617">సందర్భోచిత శోధనను ప్రారంభించండి.</translation>
 <translation id="2370882663124746154">Double-Pinyin మోడ్‌ను అనుమతించండి</translation>
@@ -2661,7 +2659,6 @@
 <translation id="4780374166989101364">ప్రయోగాత్మక పొడిగింపు APIలను ప్రారంభిస్తుంది. ప్రయోగాత్మక APIలని ఉపయోగించే పొడిగింపులను అప్‌లోడ్ చెయ్యడానికి మిమ్మల్ని పొడిగింపు గ్యాలరీ అనుమతించదని గుర్తుంచుకోండి.</translation>
 <translation id="4781787911582943401">స్క్రీన్‌ను దగ్గరకు జూమ్ చేయి</translation>
 <translation id="4782449893814226250">మీరు ఈ పేజీని సందర్శించడానికి అనుమతించమని కోరుతూ మీ తల్లిదండ్రులకు అభ్యర్థన పంపారు.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint ప్రెజెంటేషన్</translation>
 <translation id="4785040501822872973">ఈ కంప్యూటర్ <ph name="LOGOUT_TIME_LEFT" /> సెకన్లలో రీసెట్ చేయబడుతుంది.
 విశ్లేషించడాన్ని కొనసాగించడానికి ఏదైనా కీని నొక్కండి.</translation>
@@ -3192,7 +3189,6 @@
 <translation id="5527474464531963247">మీరు మరొక నెట్‌వర్క్‌ను కూడా ఎంచుకోవచ్చు.</translation>
 <translation id="5527963985407842218">రీడర్ మోడ్ ప్రారంభం</translation>
 <translation id="5528368756083817449">బుక్‌మార్క్ నిర్వాహికి</translation>
-<translation id="5529098031581368697">ప్రస్తుత వాల్‌పేపర్ '<ph name="APP_NAME" />' ద్వారా సెట్ చేయబడింది</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">సార్వజనీనం</translation>
 <translation id="5533555070048896610">లిప్యంతరీకరణ (namaste → नमस्ते)</translation>
@@ -3307,7 +3303,6 @@
 <translation id="5702898740348134351">శోధన ఇంజిన్లను &amp;సవరించు...</translation>
 <translation id="5703594190584829406">స్వీయ పూరింపు సూచనలను డ్రాప్‌డౌన్‌లో కాకుండా కీబోర్డ్ పైన చూపుతుంది.</translation>
 <translation id="5704272569086782895">థ్రెడెడ్ GPU రాస్టరైజేషన్‌ను ప్రారంభించండి.</translation>
-<translation id="570544101664452060">ప్రయోగాత్మక WebUsb నోటిఫికేషన్‌లు.</translation>
 <translation id="5706551819490830015">బిల్లింగ్ చిరునామాలను నిర్వహించండి...</translation>
 <translation id="5707185214361380026">దీని నుండి పొడిగింపుని లోడ్ చేయడంలో విఫలమైంది:</translation>
 <translation id="5707604204219538797">తదుపరి పదం</translation>
@@ -3456,7 +3451,6 @@
 <translation id="5900302528761731119">Google ప్రొఫైల్ ఫోటో</translation>
 <translation id="5900623698597156974">TLS 1.0 ఫాల్‌బ్యాక్ సర్వర్‌తో కనెక్షన్‌ను ఏర్పాటు చేయగలదు, కానీ మేము TLS 1.0 ఫాల్‌బ్యాక్‌లను ఆమోదించము. సంస్కరణ సంధానాన్ని సరైన రీతిలో అమలు చేయడానికి మరియు ముఖ్యంగా TLS 1.2కి మద్దతివ్వడానికి సర్వర్‌‌ను నవీకరించాలి.</translation>
 <translation id="590253956165195626">మీరు చదివే భాషలో లేని పేజీలకు అనువాదాన్ని ఆఫర్ చేయాలి.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 అంశం}other{# అంశాలు}}</translation>
 <translation id="5904093760909470684">ప్రాక్సీ కాన్ఫిగరేషన్</translation>
 <translation id="5906065664303289925">హార్డ్‌వేర్ చిరునామా:</translation>
 <translation id="5910363049092958439">చిత్రాన్ని ఇలా సే&amp;వ్ చెయ్యి...</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb
index 7735adf4..b9450d9 100644
--- a/chrome/app/resources/generated_resources_th.xtb
+++ b/chrome/app/resources/generated_resources_th.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">เข้าถึงอุปกรณ์ USB ใดๆ ก็ได้เหล่านี้</translation>
 <translation id="1038168778161626396">เข้ารหัสเท่านั้น</translation>
 <translation id="1038842779957582377">ไม่ทราบชื่อ</translation>
-<translation id="1040931876666128942">การแจ้งเตือน WebUsb</translation>
 <translation id="1042174272890264476">คอมพิวเตอร์ของคุณมาพร้อมกับไลบรารี RLZ ของ <ph name="SHORT_PRODUCT_NAME" /> ในตัว โดย RLZ จะระบุแท็กที่ซ้ำกันได้และไม่สามารถระบุตัวบุคคลเพื่อวัดการค้นหาและการใช้งาน <ph name="SHORT_PRODUCT_NAME" /> ที่ทำงานโดยแคมเปญส่งเสริมการขายบางรายการ บางครั้งป้ายกำกับจะปรากฏในคำค้นหาของ Google Search ใน <ph name="PRODUCT_NAME" /></translation>
 <translation id="1042574203789536285"><ph name="URL" /> ต้องการจัดเก็บข้อมูลขนาดใหญ่อย่างถาวรในอุปกรณ์ของคุณ</translation>
 <translation id="1045157690796831147">การทับศัพท์ (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">การตั้งค่าคุกกี้ใหม่จะแสดงผลหลังจากการโหลดหน้านี้อีกครั้ง</translation>
 <translation id="14720830734893704">เปิดใช้งานการสนับสนุนแป้นพิมพ์เสมือน</translation>
 <translation id="1474339897586437869">ไม่ได้อัปโหลด "<ph name="FILENAME" />" มีพื้นที่ว่างไม่เพียงพอใน Google ไดรฟ์ของคุณ</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{รหัสผ่าน 1 รายการ}other{รหัสผ่าน # รายการ}}</translation>
 <translation id="1476949146811612304">ตั้งค่าว่าจะใช้เครื่องมือค้นหาใดเมื่อค้นหาจาก<ph name="BEGIN_LINK" />แถบอเนกประสงค์<ph name="END_LINK" /></translation>
 <translation id="1477301030751268706">แคชโทเค็น API ข้อมูลประจำตัว</translation>
 <translation id="1478340334823509079">รายละเอียด: <ph name="FILE_NAME" /></translation>
@@ -920,6 +918,7 @@
 <translation id="2326606747676847821">เข้าโหมดไม่ระบุตัวตน</translation>
 <translation id="2326931316514688470">โ&amp;หลดแอปซ้ำ</translation>
 <translation id="2327492829706409234">เปิดใช้งานแอปพลิเคชัน</translation>
+<translation id="2329597144923131178">ลงชื่อเข้าใช้เพื่อรับบุ๊กมาร์ก ประวัติ รหัสผ่าน และการตั้งค่าอื่นๆ ในอุปกรณ์ทั้งหมด</translation>
 <translation id="2332131598580221120">ดูในสโตร์</translation>
 <translation id="2332742915001411729">รีเซ็ตเป็นค่าเริ่มต้น</translation>
 <translation id="2335122562899522968">หน้าเว็บนี้ได้บันทึกคุกกี้แล้ว</translation>
@@ -943,7 +942,6 @@
 <translation id="2359808026110333948">ดำเนินการต่อ</translation>
 <translation id="236128817791440714">แนะนำ: ตั้งค่า Smart Lock สำหรับ Android</translation>
 <translation id="236141728043665931">บล็อกการเข้าถึงไมโครโฟนเสมอ</translation>
-<translation id="2365626167708453863">เลือกบัญชีจาก Google Smart Lock</translation>
 <translation id="2367972762794486313">แสดงแอป</translation>
 <translation id="2368075211218459617">เปิดใช้ค้นหาตามบริบท</translation>
 <translation id="2370882663124746154">เปิดการใช้งานโหมด Double-Pinyin</translation>
@@ -1043,7 +1041,7 @@
 <translation id="2501173422421700905">ใบรับรองถูกระงับไว้</translation>
 <translation id="2501278716633472235">ย้อนกลับ</translation>
 <translation id="2501797496290880632">พิมพ์แป้นพิมพ์ลัด</translation>
-<translation id="2502441965851148920">เปิดใช้การอัปเดตอัตโนมัติอยู่ ผู้ดูแลระบบปิดใช้การอัปเดตด้วยตนเอง</translation>
+<translation id="2502441965851148920">เปิดใช้การอัปเดตอัตโนมัติอยู่ ผู้ดูแลระบบได้ปิดใช้การอัปเดตด้วยตนเอง</translation>
 <translation id="2504775205691825589">เซิร์ฟเวอร์ที่โฮสต์หน้าเว็บนี้อาจโหลดมากเกินไปหรืออยู่ระหว่างการซ่อมบำรุง
         ทั้งนี้เพื่อหลีกเลี่ยงการเพิ่มการจราจรข้อมูลมากเกินไปและทำให้สถานการณ์แย่ลง
         ระบบจะไม่อนุญาตให้ส่งคำขอไปยัง URL นี้ชั่วคราว</translation>
@@ -2652,7 +2650,6 @@
 <translation id="4780374166989101364">เปิดใช้งาน API ส่วนขยายที่อยู่ในช่วงทดลอง โปรดทราบว่าแกลเลอรีส่วนขยายไม่อนุญาตให้คุณอัปโหลดส่วนขยายที่ใช้ API ที่อยู่ในช่วงทดลอง</translation>
 <translation id="4781787911582943401">ขยายหน้าจอ</translation>
 <translation id="4782449893814226250">คุณถามผู้ปกครองว่าสามารถเข้าชมหน้านี้ได้ไหมแล้ว</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">งานนำเสนอ PowerPoint</translation>
 <translation id="4785040501822872973">คอมพิวเตอร์นี้จะรีเซ็ตภายใน <ph name="LOGOUT_TIME_LEFT" /> วินาที
 กดแป้นใดก็ได้เพื่อสำรวจต่อ</translation>
@@ -3183,7 +3180,6 @@
 <translation id="5527474464531963247">คุณสามารถเลือกเครือข่ายอื่นได้ด้วย</translation>
 <translation id="5527963985407842218">การทริกเกอร์โหมดนักอ่าน</translation>
 <translation id="5528368756083817449">ตัวจัดการบุ๊กมาร์ก</translation>
-<translation id="5529098031581368697">วอลเปเปอร์ปัจจุบันตั้งโดย "<ph name="APP_NAME" />"</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">ทั่วโลก</translation>
 <translation id="5533555070048896610">การทับศัพท์ (namaste → नमस्ते)</translation>
@@ -3299,7 +3295,6 @@
 <translation id="5702898740348134351">แ&amp;ก้ไขเครื่องมือค้นหา...</translation>
 <translation id="5703594190584829406">แสดงคำแนะนำการป้อนข้อความอัตโนมัติที่ด้านบนของแป้นพิมพ์แทนที่จะแสดงในรายการแบบเลื่อนลง</translation>
 <translation id="5704272569086782895">เปิดใช้การแรสเตอร์ GPU แบบเธร็ด</translation>
-<translation id="570544101664452060">การแจ้งเตือน WebUsb แบบทดลอง</translation>
 <translation id="5706551819490830015">จัดการที่อยู่สำหรับการเรียกเก็บเงิน...</translation>
 <translation id="5707185214361380026">ไม่สามารถโหลดส่วนขยายจาก:</translation>
 <translation id="5707604204219538797">คำถัดไป</translation>
@@ -3447,7 +3442,6 @@
 <translation id="5900302528761731119">รูปภาพ Google โปรไฟล์</translation>
 <translation id="5900623698597156974">การกลับไปใช้ TLS 1.0 สามารถทำงานกับเซิร์ฟเวอร์ได้ แต่เราไม่ยอมรับการกลับไปใช้ TLS 1.0 อีกแล้ว ต้องมีการอัปเดตเซิร์ฟเวอร์เพื่อใช้การจัดการเวอร์ชันได้อย่างถูกต้อง และเซิร์ฟเวอร์ควรจะรองรับ TLS 1.2</translation>
 <translation id="590253956165195626">ข้อเสนอในการแปลหน้าที่ไม่ได้อยู่ในภาษาที่คุณอ่านได้</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 รายการ}other{# รายการ}}</translation>
 <translation id="5904093760909470684">การกำหนดค่าพร็อกซี</translation>
 <translation id="5906065664303289925">ที่อยู่ฮาร์ดแวร์:</translation>
 <translation id="5910363049092958439">&amp;บันทึกรูปภาพเป็น...</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb
index 24eacc40..f1fd1d1f 100644
--- a/chrome/app/resources/generated_resources_tr.xtb
+++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Bu USB cihazların herhangi birine erişme</translation>
 <translation id="1038168778161626396">Yalnızca Şifrele</translation>
 <translation id="1038842779957582377">bilinmeyen ad</translation>
-<translation id="1040931876666128942">WebUsb bildirimleri.</translation>
 <translation id="1042174272890264476">Bilgisayarınızda aynı zamanda yerleşik <ph name="SHORT_PRODUCT_NAME" /> RLZ kitaplığı da bulunur. RLZ, aramaları ve belirli bir promosyon kampanyasının sağladığı <ph name="SHORT_PRODUCT_NAME" /> kullanımını ölçmek için benzersiz olmayan ve kimlik bilgileri içermeyen bir etiket atar. Bu etiketler bazen <ph name="PRODUCT_NAME" /> içindeki Google Arama sorgularında görünür.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> büyük miktarda veriyi cihazınızda kalıcı olarak depolamak istiyor.</translation>
 <translation id="1045157690796831147">Harf çevirisi (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Yeni çerez ayarları sayfa yeniden yüklendikten sonra etkinleşecek.</translation>
 <translation id="14720830734893704">Sanal klavye desteğini etkinleştirin.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" yüklenmedi. Google Drive'ınızda yeterli boş alan yok.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 şifre}other{# şifre}}</translation>
 <translation id="1476949146811612304"><ph name="BEGIN_LINK" />Çok amaçlı adres çubuğundan<ph name="END_LINK" /> arama yaparken hangi arama motorunun kullanılacağını ayarlayın.</translation>
 <translation id="1477301030751268706">Kimlik API'sı Jeton Önbelleği</translation>
 <translation id="1478340334823509079">Ayrıntılar: <ph name="FILE_NAME" /></translation>
@@ -923,6 +921,7 @@
 <translation id="2326606747676847821">Gizli mod</translation>
 <translation id="2326931316514688470">&amp;Uygulamayı yeniden yükle</translation>
 <translation id="2327492829706409234">Uygulamayı etkinleştir</translation>
+<translation id="2329597144923131178">Yer işaretlerinize, geçmişinize ve diğer ayarlarınıza tüm cihazlarınızdan erişmek için oturum açın.</translation>
 <translation id="2332131598580221120">Mağazada görüntüle</translation>
 <translation id="2332742915001411729">Varsayılana sıfırla</translation>
 <translation id="2335122562899522968">Bu sayfa çerez ayarlar.</translation>
@@ -946,7 +945,6 @@
 <translation id="2359808026110333948">Devam Et</translation>
 <translation id="236128817791440714">Önerilen: Android için Smart Lock özelliğini kurun</translation>
 <translation id="236141728043665931">Mikrofon erişimini her zaman engelle</translation>
-<translation id="2365626167708453863">Google Smart Lock'unuzdan bir hesap seçin</translation>
 <translation id="2367972762794486313">Uygulamaları göster</translation>
 <translation id="2368075211218459617">Bağlama Dayalı Arama'yı etkinleştir.</translation>
 <translation id="2370882663124746154">Çift-Pinyin modunu etkinleştir</translation>
@@ -2663,7 +2661,6 @@
 <translation id="4780374166989101364">Deneysel uzantı API'larını etkinleştirir. Uzantı galerisinin deneysel API'lar kullanan uzantıları yüklemenize izin vermeyeceğini unutmayın.</translation>
 <translation id="4781787911582943401">Ekranı yakınlaştır</translation>
 <translation id="4782449893814226250">Ebeveynlerinize, bu sayfayı ziyaret etmenizin uygun olup olmadığını sordunuz.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">PowerPoint sunusu</translation>
 <translation id="4785040501822872973">Bu bilgisayar <ph name="LOGOUT_TIME_LEFT" /> saniye içinde sıfırlanacak.
 Keşfetmeye devam etmek için herhangi bir tuşa basın.</translation>
@@ -3194,7 +3191,6 @@
 <translation id="5527474464531963247">Başka bir ağ da seçebilirsiniz.</translation>
 <translation id="5527963985407842218">Okuyucu Modu'nun tetiklenmesi</translation>
 <translation id="5528368756083817449">Yer İşareti Yöneticisi</translation>
-<translation id="5529098031581368697">Geçerli duvar kağıdı "<ph name="APP_NAME" />" tarafından ayarlandı</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Evrensel</translation>
 <translation id="5533555070048896610">Harf çevirisi (namaste → नमस्ते)</translation>
@@ -3310,7 +3306,6 @@
 <translation id="5702898740348134351">&amp;Arama Motorlarını Düzenle...</translation>
 <translation id="5703594190584829406">Otomatik Doldur önerilerini bir açılır liste yerine klavyenin üstünde gösterir.</translation>
 <translation id="5704272569086782895">Dizi halinde GPU pikselleştirmesini etkinleştirin.</translation>
-<translation id="570544101664452060">Deneysel WebUsb bildirimleri.</translation>
 <translation id="5706551819490830015">Faturalandırma adreslerini yönet...</translation>
 <translation id="5707185214361380026">Uzantı şuradan yüklenemedi:</translation>
 <translation id="5707604204219538797">Sonraki kelime</translation>
@@ -3459,7 +3454,6 @@
 <translation id="5900302528761731119">Google Profil fotoğrafı</translation>
 <translation id="5900623698597156974">Bir TLS 1.0 yedeği, sunucu ile anlaşabildi, ancak artık TLS 1.0 yedeklerini kabul etmiyoruz. Sunucunun sürüm anlaşmasını doğru şekilde yapabilmesi ve tercihen TLS 1.2'yi desteklemesi için güncellenmesi gerekiyor.</translation>
 <translation id="590253956165195626">Okuduğum dilde olmayan sayfaları çevirmeyi öner.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 öğe}other{# öğe}}</translation>
 <translation id="5904093760909470684">Proxy yapılandırması</translation>
 <translation id="5906065664303289925">Donanım adresi:</translation>
 <translation id="5910363049092958439">Resmi Farklı Ka&amp;ydet...</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb
index a09b4b9..6ac569c 100644
--- a/chrome/app/resources/generated_resources_uk.xtb
+++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Отримувтаи доступ до цих пристроїв USB</translation>
 <translation id="1038168778161626396">Тільки шифрувати</translation>
 <translation id="1038842779957582377">Невідоме ім’я</translation>
-<translation id="1040931876666128942">Сповіщення WebUsb.</translation>
 <translation id="1042174272890264476">Ваш комп’ютер також має вбудовану бібліотеку RLZ у <ph name="SHORT_PRODUCT_NAME" />. Параметр RLZ призначає неунікальний тег, який не містить особисті дані, проте дозволяє вимірювати пошуки й користування <ph name="SHORT_PRODUCT_NAME" /> у рамках певної рекламної кампанії. Ці мітки інколи з’являються в пошукових запитах Google у <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285">Сторінка <ph name="URL" /> хоче постійно зберігати великий обсяг даних на вашому пристрої.</translation>
 <translation id="1045157690796831147">Транслітерація (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">Нові налаштування файлів cookie почнуть діяти після перезавантаження сторінки.</translation>
 <translation id="14720830734893704">Увімкнути підтримку віртуальної клавіатури.</translation>
 <translation id="1474339897586437869">Файл "<ph name="FILENAME" />" не додано. Замало вільного місця на Google Диску.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 пароль}one{# пароль}few{# паролі}many{# паролів}other{# пароля}}</translation>
 <translation id="1476949146811612304">Налаштувати, яку пошукову систему використовувати під час пошуку з <ph name="BEGIN_LINK" />універсального вікна пошуку<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Кеш маркера API ідентифікації</translation>
 <translation id="1478340334823509079">Деталі: <ph name="FILE_NAME" /></translation>
@@ -919,6 +917,7 @@
 <translation id="2326606747676847821">Відкрити в анонімному вікні</translation>
 <translation id="2326931316514688470">&amp;Перезавантажити додаток</translation>
 <translation id="2327492829706409234">Увімкнути програму</translation>
+<translation id="2329597144923131178">Увійдіть, щоб мати доступ до закладок, історії, паролів та інших налаштувань на всіх своїх пристроях.</translation>
 <translation id="2332131598580221120">Переглянути в магазині</translation>
 <translation id="2332742915001411729">Відновити масштаб за умовчанням</translation>
 <translation id="2335122562899522968">Ця сторінка налаштувала файли cookie.</translation>
@@ -942,7 +941,6 @@
 <translation id="2359808026110333948">Продовжити</translation>
 <translation id="236128817791440714">Рекомендовано. Налаштуйте Smart Lock для Android</translation>
 <translation id="236141728043665931">Завжди блокувати доступ до мікрофона</translation>
-<translation id="2365626167708453863">Виберіть обліковий запис із Google Smart Lock</translation>
 <translation id="2367972762794486313">Показати програми</translation>
 <translation id="2368075211218459617">Увімкнути контекстний пошук.</translation>
 <translation id="2370882663124746154">Увімкнути режим подвійного введення для стандарту піньїнь</translation>
@@ -2651,7 +2649,6 @@
 <translation id="4780374166989101364">Вмикає API експериментальних розширень. Зауважте, що галерея розширень не дозволяє завантажувати розширення, що використовують експериментальні API.</translation>
 <translation id="4781787911582943401">Збільшити масштаб екрана</translation>
 <translation id="4782449893814226250">Ви надіслали батькам запит на перегляд цієї сторінки.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 Кб}one{# Кб}few{# Кб}many{# Кб}other{# Кб}}</translation>
 <translation id="4784330909746505604">Презентація PowerPoint</translation>
 <translation id="4785040501822872973">Цей комп’ютер буде перезавантажено через <ph name="LOGOUT_TIME_LEFT" /> сек.
 Натисніть будь-яку клавішу, щоб продовжити перегляд.</translation>
@@ -3182,7 +3179,6 @@
 <translation id="5527474464531963247">Можна також вибрати іншу мережу.</translation>
 <translation id="5527963985407842218">Активація кнопки "Режим читання"</translation>
 <translation id="5528368756083817449">Диспетчер закладок</translation>
-<translation id="5529098031581368697">Додаток "<ph name="APP_NAME" />" встановив поточний фоновий малюнок</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Загальні</translation>
 <translation id="5533555070048896610">Транслітерація (namaste → नमस्ते)</translation>
@@ -3295,7 +3291,6 @@
 <translation id="5702898740348134351">&amp;Змінити пошукові системи...</translation>
 <translation id="5703594190584829406">Пропозиції автозаповнення з’являються над клавіатурою, а не в спадному меню.</translation>
 <translation id="5704272569086782895">Увімкнути апаратну растеризацію.</translation>
-<translation id="570544101664452060">Експериментальні сповіщення WebUsb.</translation>
 <translation id="5706551819490830015">Керувати платіжними адресами…</translation>
 <translation id="5707185214361380026">Не вдалося завантажити розширення з:</translation>
 <translation id="5707604204219538797">Наступне слово</translation>
@@ -3441,7 +3436,6 @@
 <translation id="5900302528761731119">Фото профілю Googlе</translation>
 <translation id="5900623698597156974">Альтернативний до TLS 1.0 протокол міг обмінятися даними з сервером, але альтернативи до TLS 1.0 більше не приймаються. Оновіть сервер, щоб він працював із сумісною версією протоколу (бажано, з TLS 1.2).</translation>
 <translation id="590253956165195626">Пропонувати переклад сторінок, якщо їх мова відрізняється від мови у веб-переглядачі.</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 запис}one{# запис}few{# записи}many{# записів}other{# запису}}</translation>
 <translation id="5904093760909470684">Конфігурація проксі-сервера</translation>
 <translation id="5906065664303289925">Адреса апаратного забезпечення:</translation>
 <translation id="5910363049092958439">Збер&amp;егти зображення як...</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb
index 0037a13..ff2e031 100644
--- a/chrome/app/resources/generated_resources_vi.xtb
+++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">Truy cập bất kỳ trong số các thiết bị USB này</translation>
 <translation id="1038168778161626396">Chỉ Mã hóa</translation>
 <translation id="1038842779957582377">tên không biết</translation>
-<translation id="1040931876666128942">Thông báo WebUsb.</translation>
 <translation id="1042174272890264476">Máy tính của bạn cũng đi kèm với thư viện RLZ của <ph name="SHORT_PRODUCT_NAME" /> được tích hợp sẵn. RLZ chỉ định thẻ không thể nhận dạng cá nhân, không duy nhất để đo lường các tìm kiếm và mức độ sử dụng <ph name="SHORT_PRODUCT_NAME" /> mà một chiến dịch quảng cáo cụ thể mang lại. Đôi khi các nhãn này xuất hiện trong truy vấn Google Tìm kiếm trong <ph name="PRODUCT_NAME" />.</translation>
 <translation id="1042574203789536285"><ph name="URL" /> muốn lưu trữ vĩnh viễn một lượng lớn dữ liệu trên thiết bị của bạn.</translation>
 <translation id="1045157690796831147">Chuyển ngữ (namaskar → നമസ്കാരം)</translation>
@@ -329,7 +328,6 @@
 <translation id="1470719357688513792">Cài đặt cookie mới sẽ có hiệu lực sau khi tải lại trang.</translation>
 <translation id="14720830734893704">Bật hỗ trợ bàn phím ảo.</translation>
 <translation id="1474339897586437869">"<ph name="FILENAME" />" không được tải lên. Không có đủ dung lượng trống trong Google Drive của bạn.</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 mật khẩu}other{# mật khẩu}}</translation>
 <translation id="1476949146811612304">Đặt công cụ tìm kiếm được sử dụng khi tìm kiếm từ
         <ph name="BEGIN_LINK" />thanh địa chỉ<ph name="END_LINK" />.</translation>
 <translation id="1477301030751268706">Lưu bộ nhớ cache mã thông báo API nhận dạng</translation>
@@ -925,6 +923,7 @@
 <translation id="2326606747676847821">Truy cập ẩn danh</translation>
 <translation id="2326931316514688470">Tải &amp;lại ứng dụng</translation>
 <translation id="2327492829706409234">Bật ứng dụng</translation>
+<translation id="2329597144923131178">Đăng nhập để nhận dấu trang, lịch sử, mật khẩu và các cài đặt khác trên tất cả các thiết bị của bạn.</translation>
 <translation id="2332131598580221120">Xem trong cửa hàng</translation>
 <translation id="2332742915001411729">Đặt lại về mặc định</translation>
 <translation id="2335122562899522968">Trang này đã đặt các cookie.</translation>
@@ -948,7 +947,6 @@
 <translation id="2359808026110333948">Tiếp tục</translation>
 <translation id="236128817791440714">Khuyến nghị: Thiết lập Smart Lock dành cho Android</translation>
 <translation id="236141728043665931">Luôn chặn quyền truy cập micrô</translation>
-<translation id="2365626167708453863">Chọn tài khoản từ Google Smart Lock của bạn</translation>
 <translation id="2367972762794486313">Hiển thị ứng dụng</translation>
 <translation id="2368075211218459617">Bật tìm kiếm theo ngữ cảnh.</translation>
 <translation id="2370882663124746154">Bật chế độ Double-Pinyin</translation>
@@ -1007,7 +1005,7 @@
 <translation id="2448046586580826824">Proxy HTTP bảo mật</translation>
 <translation id="2448312741937722512">Loại</translation>
 <translation id="2449267011068443460">Không cho phép</translation>
-<translation id="2450223707519584812">Bạn không thể thêm người dùng vì thiếu khóa API của Google. Xem <ph name="DETAILS_URL" /> để biết thông tin chi tiết.</translation>
+<translation id="2450223707519584812">Bạn không thể thêm người dùng vì thiếu khóa Google API. Xem <ph name="DETAILS_URL" /> để biết thông tin chi tiết.</translation>
 <translation id="2450531422290975480">Nếu bạn hiểu các rủi ro bảo mật, bạn có thể <ph name="BEGIN_LINK" />truy cập trang web không an toàn này<ph name="END_LINK" /> (không được đề xuất) trước khi các chương trình nguy hiểm bị xóa.</translation>
 <translation id="2452539774207938933">Chuyển sang người dùng: <ph name="PROFILE_NAME" /></translation>
 <translation id="2453021845418314664">Cài đặt đồng bộ hóa nâng cao</translation>
@@ -1527,7 +1525,7 @@
 <translation id="3140353188828248647">Thanh địa chỉ chính</translation>
 <translation id="3144126448740580210">XONG</translation>
 <translation id="3144135466825225871">Không thể thay thế tệp crx. Kiểm tra để xem tệp có đang được sử dụng hay không.</translation>
-<translation id="3144647712221361880">Mở liên kết dưới dạng</translation>
+<translation id="3144647712221361880">Mở liên kết bằng tài khoản</translation>
 <translation id="31454997771848827">Miền nhóm</translation>
 <translation id="3147485256806412701">Trang web này đang sử dụng miền chung mới cấp cao nhất.</translation>
 <translation id="3149510190863420837">Ứng dụng Chrome</translation>
@@ -2668,7 +2666,6 @@
 <translation id="4780374166989101364">Bật API tiện ích thử nghiệm. Xin lưu ý rằng thư viện tiện ích không cho phép bạn tải lên tiện ích sử dụng API thử nghiệm.</translation>
 <translation id="4781787911582943401">Phóng to màn hình</translation>
 <translation id="4782449893814226250">Bạn đã hỏi cha mẹ mình xem có thể truy cập vào trang này hay không.</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 kB}other{# kB}}</translation>
 <translation id="4784330909746505604">Bản trình bày PowerPoint</translation>
 <translation id="4785040501822872973">Máy tính này sẽ đặt lại trong <ph name="LOGOUT_TIME_LEFT" /> giây.
 Nhấn phím bất kỳ để tiếp tục khám phá.</translation>
@@ -3199,7 +3196,6 @@
 <translation id="5527474464531963247">Bạn cũng có thể chọn một mạng khác.</translation>
 <translation id="5527963985407842218">Kích hoạt Chế độ đọc</translation>
 <translation id="5528368756083817449">Trình quản lý dấu trang</translation>
-<translation id="5529098031581368697">Hình nền hiện tại do '<ph name="APP_NAME" />' đặt</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">Toàn cầu</translation>
 <translation id="5533555070048896610">Chuyển ngữ (namaste → नमस्ते)</translation>
@@ -3315,7 +3311,6 @@
 <translation id="5702898740348134351">&amp;Chỉnh sửa Công cụ Tìm kiếm...</translation>
 <translation id="5703594190584829406">Hiển thị các đề xuất Tự động điền ở trên cùng của bàn phím chứ không ở trong menu thả xuống.</translation>
 <translation id="5704272569086782895">Bật tạo điểm ảnh GPU theo chuỗi.</translation>
-<translation id="570544101664452060">Thông báo WebUsb thử nghiệm.</translation>
 <translation id="5706551819490830015">Quản lý địa chỉ thanh toán...</translation>
 <translation id="5707185214361380026">Không tải được tiện ích từ:</translation>
 <translation id="5707604204219538797">Từ tiếp theo</translation>
@@ -3464,7 +3459,6 @@
 <translation id="5900302528761731119">Ảnh hồ sơ trên Google</translation>
 <translation id="5900623698597156974">Giao thức dự phòng TLS 1.0 có thể kết hợp với máy chủ nhưng chúng tôi không chấp nhận giao thức dự phòng TLS 1.0 nữa. Cần cập nhật máy chủ để triển khai đúng cách việc dàn xếp phiên bản và hỗ trợ tốt nhất cho TLS 1.2.</translation>
 <translation id="590253956165195626">Đề xuất dịch các trang tiếng nước ngoài mà bạn không hiểu </translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 mục}other{# mục}}</translation>
 <translation id="5904093760909470684">Cấu hình Proxy</translation>
 <translation id="5906065664303289925">Địa chỉ phần cứng:</translation>
 <translation id="5910363049092958439">Lưu &amp;Hình ảnh Dưới dạng...</translation>
@@ -4104,7 +4098,7 @@
 <translation id="6880587130513028875">Hình ảnh đã bị chặn trên trang này.</translation>
 <translation id="6883209331334683549">Trợ giúp của <ph name="PRODUCT_NAME" /></translation>
 <translation id="6886871292305414135">Mở liên kết trong &amp;tab mới</translation>
-<translation id="6892812721183419409">Mở liên kết dưới dạng <ph name="USER" /></translation>
+<translation id="6892812721183419409">Mở liên kết bằng tài khoản <ph name="USER" /></translation>
 <translation id="6896758677409633944">Sao chép</translation>
 <translation id="6898440773573063262">Ứng dụng kiosk giờ đây có thể được định cấu hình để tự động chạy trên thiết bị này.</translation>
 <translation id="6898699227549475383">Tổ chức (O)</translation>
@@ -5677,7 +5671,7 @@
 <translation id="9137013805542155359">Hiển thị văn bản gốc</translation>
 <translation id="9137356749601179867">Hiển thị hộp kiểm để lưu cục bộ thẻ tín dụng được tải xuống từ máy chủ.</translation>
 <translation id="913758436357682283">Bàn phím tiếng Myansan của Myanmar</translation>
-<translation id="9137916601698928395">Mở liên kết dưới dạng <ph name="USER" /></translation>
+<translation id="9137916601698928395">Mở liên kết bằng tài khoản <ph name="USER" /></translation>
 <translation id="914566504855049417">Bật dàn xếp với DTLS 1.2 cho WebRTC.</translation>
 <translation id="9147392381910171771">&amp;Tuỳ chọn</translation>
 <translation id="9148058034647219655">Thoát</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb
index a0dfa66..8747dba 100644
--- a/chrome/app/resources/generated_resources_zh-CN.xtb
+++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">访问其中的任意 USB 设备</translation>
 <translation id="1038168778161626396">仅加密</translation>
 <translation id="1038842779957582377">未知名称</translation>
-<translation id="1040931876666128942">WebUsb 通知。</translation>
 <translation id="1042174272890264476">您的计算机还内置了 <ph name="SHORT_PRODUCT_NAME" /> 的 RLZ 库。RLZ 会指定非唯一、非个人身份识别代码来衡量某推广活动所带来的搜索量和 <ph name="SHORT_PRODUCT_NAME" /> 使用量。这些标签有时会显示在 <ph name="PRODUCT_NAME" /> 的 Google 搜索查询中。</translation>
 <translation id="1042574203789536285"><ph name="URL" /> 想在您的设备上永久存储大量数据。</translation>
 <translation id="1045157690796831147">音译(namaskar → നമസ്കാരം)</translation>
@@ -327,7 +326,6 @@
 <translation id="1470719357688513792">新的 Cookie 设置会在重新加载网页后生效。</translation>
 <translation id="14720830734893704">启用虚拟键盘支持。</translation>
 <translation id="1474339897586437869">未上传“<ph name="FILENAME" />”,因为您的 Google 云端硬盘没有足够的可用空间。</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 个密码}other{# 个密码}}</translation>
 <translation id="1476949146811612304">设置在通过<ph name="BEGIN_LINK" />多功能框<ph name="END_LINK" />搜索时所用的搜索引擎。</translation>
 <translation id="1477301030751268706">Identity API 令牌缓存</translation>
 <translation id="1478340334823509079">详细信息:<ph name="FILE_NAME" /></translation>
@@ -775,7 +773,7 @@
 <translation id="2135787500304447609">继续(&amp;R)</translation>
 <translation id="2136953289241069843">音译(namaste → नमस्कार)</translation>
 <translation id="2137808486242513288">添加用户</translation>
-<translation id="2142328300403846845">将链接打开为</translation>
+<translation id="2142328300403846845">以其他身份打开链接</translation>
 <translation id="214353449635805613">截取所选区域的屏幕截图</translation>
 <translation id="2143778271340628265">手动配置代理</translation>
 <translation id="2143915448548023856">显示设备设置</translation>
@@ -920,6 +918,7 @@
 <translation id="2326606747676847821">进入隐身模式</translation>
 <translation id="2326931316514688470">重新加载应用(&amp;R)</translation>
 <translation id="2327492829706409234">启用应用</translation>
+<translation id="2329597144923131178">登录后可获取您所有设备上保存的书签、历史记录、密码和其他设置。</translation>
 <translation id="2332131598580221120">在应用店中查看</translation>
 <translation id="2332742915001411729">重置为默认设置</translation>
 <translation id="2335122562899522968">该页用于设置 Cookie。</translation>
@@ -943,7 +942,6 @@
 <translation id="2359808026110333948">继续</translation>
 <translation id="236128817791440714">推荐:设置 Smart Lock(Android 版)</translation>
 <translation id="236141728043665931">始终禁止使用麦克风</translation>
-<translation id="2365626167708453863">从 Google Smart Lock 中选择帐户</translation>
 <translation id="2367972762794486313">显示应用</translation>
 <translation id="2368075211218459617">启用环境相关搜索。</translation>
 <translation id="2370882663124746154">启用双拼模式</translation>
@@ -1517,7 +1515,7 @@
 <translation id="3140353188828248647">将地址栏设为焦点</translation>
 <translation id="3144126448740580210">完成</translation>
 <translation id="3144135466825225871">未能替换 CRX 文件。请检查该文件是否正在使用。</translation>
-<translation id="3144647712221361880">将链接打开为</translation>
+<translation id="3144647712221361880">以其他身份打开链接</translation>
 <translation id="31454997771848827">按域分组</translation>
 <translation id="3147485256806412701">此网站使用的是新的通用顶级域名。</translation>
 <translation id="3149510190863420837">Chrome 应用</translation>
@@ -2635,7 +2633,6 @@
 <translation id="4780374166989101364">启用实验性扩展程序 API。请注意,扩展程序库不允许上传使用实验性 API 的扩展程序。</translation>
 <translation id="4781787911582943401">放大屏幕</translation>
 <translation id="4782449893814226250">已向您父母提出允许您访问此网页的请求。</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}other{# KB}}</translation>
 <translation id="4784330909746505604">PowerPoint 演示文稿</translation>
 <translation id="4785040501822872973">此计算机将在 <ph name="LOGOUT_TIME_LEFT" /> 秒后重置。
 按任意键以继续浏览。</translation>
@@ -3163,7 +3160,6 @@
 <translation id="5527474464531963247">您也可以选择其他网络。</translation>
 <translation id="5527963985407842218">“阅读器模式”触发条件</translation>
 <translation id="5528368756083817449">书签管理器</translation>
-<translation id="5529098031581368697">当前壁纸是由“<ph name="APP_NAME" />”设置的</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">全局</translation>
 <translation id="5533555070048896610">音译(namaste → नमस्ते)</translation>
@@ -3278,7 +3274,6 @@
 <translation id="5702898740348134351">修改搜索引擎(&amp;E)...</translation>
 <translation id="5703594190584829406">在键盘顶部(而非下拉菜单中)显示自动填充建议。</translation>
 <translation id="5704272569086782895">启用线程式 GPU 栅格化。</translation>
-<translation id="570544101664452060">WebUsb 通知(实验性功能)。</translation>
 <translation id="5706551819490830015">管理帐单邮寄地址…</translation>
 <translation id="5707185214361380026">无法加载以下来源的扩展程序:</translation>
 <translation id="5707604204219538797">下一个字</translation>
@@ -3424,7 +3419,6 @@
 <translation id="5900302528761731119">Google 个人资料照片</translation>
 <translation id="5900623698597156974">TLS 1.0 回退能够与服务器握手,但我们已不再接受 TLS 1.0 回退。服务器需要更新,以便正确实现版本协商(最好能支持 TLS 1.2)。</translation>
 <translation id="590253956165195626">询问是否翻译非您所用语言的网页。</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 项内容}other{# 项内容}}</translation>
 <translation id="5904093760909470684">代理配置</translation>
 <translation id="5906065664303289925">硬件地址:</translation>
 <translation id="5910363049092958439">图片存储为(&amp;V)...</translation>
@@ -3920,7 +3914,7 @@
 <translation id="666541661050183336">降低 iframe 资源的加载优先级。</translation>
 <translation id="6666647326143344290">使用您的 Google 帐户</translation>
 <translation id="6667102209320924827">停用显示器颜色校准。</translation>
-<translation id="6675665718701918026">定点设备已连接</translation>
+<translation id="6675665718701918026">已连接指针设备</translation>
 <translation id="6677037229676347494">正确 ID 应为“<ph name="EXPECTED_ID" />”,但实际 ID 为“<ph name="NEW_ID" />”。</translation>
 <translation id="6680028776254050810">切换用户</translation>
 <translation id="6681668084120808868">拍照</translation>
@@ -4057,7 +4051,7 @@
 <translation id="6880587130513028875">已拦截此网页上的图片。</translation>
 <translation id="6883209331334683549"><ph name="PRODUCT_NAME" />帮助</translation>
 <translation id="6886871292305414135">在新标签页中打开链接(&amp;T)</translation>
-<translation id="6892812721183419409">将链接打开为 <ph name="USER" /></translation>
+<translation id="6892812721183419409">以 <ph name="USER" /> 身份打开链接</translation>
 <translation id="6896758677409633944">复制</translation>
 <translation id="6898440773573063262">信息亭模式下的应用现在可配置为在此设备上自动启动。</translation>
 <translation id="6898699227549475383">组织 (O)</translation>
@@ -5608,7 +5602,7 @@
 <translation id="9137013805542155359">显示原始网页</translation>
 <translation id="9137356749601179867">显示相应复选框,以便指定是否在本地保存从服务器下载的信用卡数据。</translation>
 <translation id="913758436357682283">缅甸语Myansan键盘</translation>
-<translation id="9137916601698928395">将链接打开为 <ph name="USER" /></translation>
+<translation id="9137916601698928395">以 <ph name="USER" /> 身份打开链接</translation>
 <translation id="914566504855049417">为 WebRTC 启用 DTLS 1.2 协商。</translation>
 <translation id="9147392381910171771">选项(&amp;O)</translation>
 <translation id="9148058034647219655">退出</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb
index 4e2ab46a..8d15683 100644
--- a/chrome/app/resources/generated_resources_zh-TW.xtb
+++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -29,7 +29,6 @@
 <translation id="1036511912703768636">存取下列任一 USB 裝置</translation>
 <translation id="1038168778161626396">只有 Encipher</translation>
 <translation id="1038842779957582377">不明名稱</translation>
-<translation id="1040931876666128942">WebUsb 通知。</translation>
 <translation id="1042174272890264476">您的電腦也內建了 <ph name="SHORT_PRODUCT_NAME" /> 的 RLZ 程式庫。RLZ 可指定非重複、非個人的可辨識標記,以評估特定宣傳廣告活動所提升的搜尋數與 <ph name="SHORT_PRODUCT_NAME" /> 使用量。這些標籤有時也會顯示在 <ph name="PRODUCT_NAME" /> 的 Google 搜尋查詢中。</translation>
 <translation id="1042574203789536285"><ph name="URL" /> 要求在您的裝置上永久儲存大量資料。</translation>
 <translation id="1045157690796831147">音譯 (namaskar → നമസ്കാരം)</translation>
@@ -328,7 +327,6 @@
 <translation id="1470719357688513792">新的 Cookie 設定會在重新載入網頁後生效。</translation>
 <translation id="14720830734893704">啟用虛擬鍵盤支援。</translation>
 <translation id="1474339897586437869">您的 Google 雲端硬碟的可用空間不足,因此無法上傳「<ph name="FILENAME" />」。</translation>
-<translation id="1476503841242751994">{COUNT,plural, =1{1 組密碼}other{# 組密碼}}</translation>
 <translation id="1476949146811612304">設定透過<ph name="BEGIN_LINK" />網址列<ph name="END_LINK" />進行搜尋時要使用哪個搜尋引擎。</translation>
 <translation id="1477301030751268706">Identity API 憑證快取</translation>
 <translation id="1478340334823509079">詳細資料:<ph name="FILE_NAME" /></translation>
@@ -922,6 +920,7 @@
 <translation id="2326606747676847821">進入無痕模式</translation>
 <translation id="2326931316514688470">重新載入應用程式(&amp;R)</translation>
 <translation id="2327492829706409234">啟用應用程式</translation>
+<translation id="2329597144923131178">登入後,即可從您使用的任何裝置取得自己的書籤、歷史紀錄、密碼和其他設定。</translation>
 <translation id="2332131598580221120">前往商店查看</translation>
 <translation id="2332742915001411729">重設為預設值</translation>
 <translation id="2335122562899522968">這個網頁會設定 Cookie。</translation>
@@ -945,7 +944,6 @@
 <translation id="2359808026110333948">繼續</translation>
 <translation id="236128817791440714">建議操作:設定 Android Smart Lock</translation>
 <translation id="236141728043665931">一律封鎖存取麥克風</translation>
-<translation id="2365626167708453863">從您的 Google Smart Lock 選擇帳戶</translation>
 <translation id="2367972762794486313">顯示應用程式</translation>
 <translation id="2368075211218459617">啟用內容比對搜尋。</translation>
 <translation id="2370882663124746154">啟用雙拼輸入模式</translation>
@@ -2650,7 +2648,6 @@
 <translation id="4780374166989101364">啟用實驗性擴充功能 API。請注意,任何使用了實驗性 API 的擴充功能都無法上傳到擴充功能庫。</translation>
 <translation id="4781787911582943401">放大畫面</translation>
 <translation id="4782449893814226250">您已詢問家長是否同意您造訪這個網頁。</translation>
-<translation id="4784085458903013712">{COUNT,plural, =1{1 KB}other{# KB}}</translation>
 <translation id="4784330909746505604">PowerPoint 簡報</translation>
 <translation id="4785040501822872973">這台電腦將在 <ph name="LOGOUT_TIME_LEFT" /> 秒後重設。
 按下任何按鍵即可繼續瀏覽。</translation>
@@ -3179,7 +3176,6 @@
 <translation id="5527474464531963247">您也可以選取其他網路。</translation>
 <translation id="5527963985407842218">閱讀器模式觸發</translation>
 <translation id="5528368756083817449">書籤管理員</translation>
-<translation id="5529098031581368697">目前使用的桌布是由「<ph name="APP_NAME" />」設定</translation>
 <translation id="5531274207066050939">Google Payments</translation>
 <translation id="5532223876348815659">通用</translation>
 <translation id="5533555070048896610">音譯 (namaste → नमस्ते)</translation>
@@ -3295,7 +3291,6 @@
 <translation id="5702898740348134351">編輯搜尋引擎(&amp;E)...</translation>
 <translation id="5703594190584829406">在鍵盤最上方顯示自動填入建議,而不要以下拉式選單顯示。</translation>
 <translation id="5704272569086782895">啟用執行緒 GPU 點陣化。</translation>
-<translation id="570544101664452060">實驗性 WebUsb 通知。</translation>
 <translation id="5706551819490830015">編輯帳單地址...</translation>
 <translation id="5707185214361380026">無法載入下列來源的擴充功能:</translation>
 <translation id="5707604204219538797">下一個字詞</translation>
@@ -3443,7 +3438,6 @@
 <translation id="5900302528761731119">Google 個人資料相片</translation>
 <translation id="5900623698597156974">TLS 1.0 候補可與伺服器進行交握,但我們已不再接受 TLS 1.0 候補。請更新伺服器,讓伺服器正確實作版本交涉 (建議更新至支援 TLS 1.2)。</translation>
 <translation id="590253956165195626">詢問是否將網頁翻譯成您所用的語言。</translation>
-<translation id="5902659428109355177">{COUNT,plural, =1{1 個項目}other{# 個項目}}</translation>
 <translation id="5904093760909470684">Proxy 設定</translation>
 <translation id="5906065664303289925">硬體位址:</translation>
 <translation id="5910363049092958439">另存圖片(&amp;V)...</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fa.xtb b/chrome/app/resources/google_chrome_strings_fa.xtb
index 301e2d7..aecb340 100644
--- a/chrome/app/resources/google_chrome_strings_fa.xtb
+++ b/chrome/app/resources/google_chrome_strings_fa.xtb
@@ -147,7 +147,7 @@
 <translation id="5931853610562009806">‏در Mac ممکن است گذرواژه‌ها در Keychain شما ذخیره شوند و سایر کاربران Chrome که این حساب OS X را دارند به آن دسترسی داشته باشند یا بتوانند همگام‌سازی کنند.</translation>
 <translation id="5940385492829620908">‏وب، نشانک‌ها و موارد دیگر Chrome شما در اینجا هستند.</translation>
 <translation id="5941830788786076944">‏Google Chrome مرورگر پیش‌فرض شود</translation>
-<translation id="597770749449734237">‏میانبرهای اضافی صفحه‌کلید را که برای اشکال زدایی Google Chrome مفید هستند، فعال می‌کند.</translation>
+<translation id="597770749449734237">‏میان‌برهای اضافی صفحه‌کلید را که برای اشکال زدایی Google Chrome مفید هستند، فعال می‌کند.</translation>
 <translation id="6011049234605203654">‏به
           منوی Chrome &gt;
           <ph name="SETTINGS_TITLE" />
diff --git a/chrome/app/resources/google_chrome_strings_no.xtb b/chrome/app/resources/google_chrome_strings_no.xtb
index 8af1450..5fa4d12 100644
--- a/chrome/app/resources/google_chrome_strings_no.xtb
+++ b/chrome/app/resources/google_chrome_strings_no.xtb
@@ -41,7 +41,7 @@
 <translation id="2286950485307333924">Nå er du logget på Chrome</translation>
 <translation id="2290014774651636340">API-nøkler for Google mangler. Noe funksjonalitet i Google Chrome blir deaktivert.</translation>
 <translation id="2290095356545025170">Er du sikker på at du vil avinstallere Google Chrome?</translation>
-<translation id="2316129865977710310">Nei takk</translation>
+<translation id="2316129865977710310">Nei, takk</translation>
 <translation id="2334084861041072223">Copyright <ph name="YEAR" /> Google Inc. Med enerett.</translation>
 <translation id="2346876346033403680">Noen har tidligere logget seg på Chrome på denne datamaskinen som <ph name="ACCOUNT_EMAIL_LAST" />. Hvis det ikke er kontoen din, må du opprette en ny Chrome-bruker for å holde informasjonen din atskilt.
 
@@ -213,7 +213,7 @@
 <translation id="7436949144778751379">Google Chrome krever Windows XP eller nyere. Enkelte funksjoner vil kanskje ikke fungere.</translation>
 <translation id="7459554271817304652">Konfigurer Synkronisering til å lagre de personlig tilpassede nettleserfunksjonene dine på nettet slik at du kan bruke dem fra Google Chrome på enhver datamaskin.</translation>
 <translation id="7473136999113284234">Chrome oppdateres automatisk, sånn at du alltid har den nyeste versjonen.</translation>
-<translation id="7473891865547856676">Nei takk</translation>
+<translation id="7473891865547856676">Nei, takk</translation>
 <translation id="7494905215383356681">Åpen kildekode-lisenser for Chrome</translation>
 <translation id="7592736734348559088">Google Chrome kunne ikke synkronisere dataene dine. Dette skyldes at påloggingsopplysningene for kontoen din er foreldede.</translation>
 <translation id="7626032353295482388">Velkommen til Chrome</translation>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 7cba4ca..fd73bacc 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -159,7 +159,7 @@
     "//components/security_interstitials/core",
     "//components/signin/core/browser",
     "//components/ssl_errors",
-    "//components/startup_metric_utils/browser",
+    "//components/startup_metric_utils",
     "//components/strings",
     "//components/suggestions",
     "//components/sync_bookmarks",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index cec7406e..8cfb51e 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -96,8 +96,9 @@
   "+components/signin",
   "+components/ssl_config",
   "+components/ssl_errors",
-  "+components/startup_metric_utils/browser",
+  "+components/startup_metric_utils",
   "+components/storage_monitor",
+  "+components/strings",
   "+components/suggestions",
   "+components/sync_bookmarks",
   "+components/sync_driver",
diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate.cc b/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
index 8ee454b25..f14cca3 100644
--- a/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
+++ b/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
@@ -9,14 +9,18 @@
 #include "base/base64.h"
 #include "base/command_line.h"
 #include "base/json/json_string_value_serializer.h"
+#include "base/prefs/pref_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/android/contextualsearch/resolved_search_term.h"
 #include "chrome/browser/android/proto/client_discourse_context.pb.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/translate/translate_service.h"
+#include "chrome/common/pref_names.h"
 #include "components/search_engines/template_url_service.h"
 #include "components/variations/net/variations_http_header_provider.h"
 #include "components/variations/variations_associated_data.h"
@@ -39,6 +43,7 @@
 const char kContextualSearchResponseDisplayTextParam[] = "display_text";
 const char kContextualSearchResponseSelectedTextParam[] = "selected_text";
 const char kContextualSearchResponseSearchTermParam[] = "search_term";
+const char kContextualSearchResponseLanguageParam[] = "lang";
 const char kContextualSearchResponseResolvedTermParam[] = "resolved_term";
 const char kContextualSearchPreventPreload[] = "prevent_preload";
 const char kContextualSearchMentions[] = "mentions";
@@ -147,15 +152,17 @@
   int mention_end = 0;
   int start_adjust = 0;
   int end_adjust = 0;
+  std::string context_language;
+  std::string target_language;
 
   if (source->GetStatus().is_success() && response_code == 200) {
     std::string response;
     bool has_string_response = source->GetResponseAsString(&response);
     DCHECK(has_string_response);
     if (has_string_response) {
-      DecodeSearchTermsFromJsonResponse(response, &search_term, &display_text,
-                                        &alternate_term, &prevent_preload,
-                                        &mention_start, &mention_end);
+      DecodeSearchTermFromJsonResponse(
+          response, &search_term, &display_text, &alternate_term,
+          &prevent_preload, &mention_start, &mention_end, &context_language);
       if (mention_start != 0 || mention_end != 0) {
         // Sanity check that our selection is non-zero and it is less than
         // 100 characters as that would make contextual search bar hide.
@@ -175,9 +182,11 @@
     }
   }
   bool is_invalid = response_code == net::URLFetcher::RESPONSE_CODE_INVALID;
-  search_term_callback_.Run(
+  ResolvedSearchTerm resolved_search_term(
       is_invalid, response_code, search_term, display_text, alternate_term,
-      prevent_preload == kDoPreventPreloadValue, start_adjust, end_adjust);
+      prevent_preload == kDoPreventPreloadValue, start_adjust, end_adjust,
+      context_language);
+  search_term_callback_.Run(resolved_search_term);
 
   // The ContextualSearchContext is consumed once the request has completed.
   context_.reset();
@@ -415,16 +424,33 @@
   return true;
 }
 
+// Gets the target language from the translate service using the user's profile.
+std::string ContextualSearchDelegate::GetTargetLanguage() {
+  Profile* profile = ProfileManager::GetActiveUserProfile();
+  PrefService* pref_service = profile->GetPrefs();
+  std::string result = TranslateService::GetTargetLanguage(pref_service);
+  DCHECK(!result.empty());
+  return result;
+}
+
+// Returns the accept languages preference string.
+std::string ContextualSearchDelegate::GetAcceptLanguages() {
+  Profile* profile = ProfileManager::GetActiveUserProfile();
+  PrefService* pref_service = profile->GetPrefs();
+  return pref_service->GetString(prefs::kAcceptLanguages);
+}
+
 // Decodes the given response from the search term resolution request and sets
 // the value of the given parameters.
-void ContextualSearchDelegate::DecodeSearchTermsFromJsonResponse(
+void ContextualSearchDelegate::DecodeSearchTermFromJsonResponse(
     const std::string& response,
     std::string* search_term,
     std::string* display_text,
     std::string* alternate_term,
     std::string* prevent_preload,
     int* mention_start,
-    int* mention_end) {
+    int* mention_end,
+    std::string* lang) {
   bool contains_xssi_escape = response.find(kXssiEscape) == 0;
   const std::string& proper_json =
       contains_xssi_escape ? response.substr(strlen(kXssiEscape)) : response;
@@ -436,6 +462,7 @@
         static_cast<base::DictionaryValue*>(root.get());
     dict->GetString(kContextualSearchPreventPreload, prevent_preload);
     dict->GetString(kContextualSearchResponseSearchTermParam, search_term);
+    dict->GetString(kContextualSearchResponseLanguageParam, lang);
     // For the display_text, if not present fall back to the "search_term".
     if (!dict->GetString(kContextualSearchResponseDisplayTextParam,
                          display_text)) {
diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate.h b/chrome/browser/android/contextualsearch/contextual_search_delegate.h
index 13b26ee..e6fdc78 100644
--- a/chrome/browser/android/contextualsearch/contextual_search_delegate.h
+++ b/chrome/browser/android/contextualsearch/contextual_search_delegate.h
@@ -11,6 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/android/contextualsearch/contextual_search_context.h"
+#include "chrome/browser/android/contextualsearch/resolved_search_term.h"
 #include "content/public/browser/android/content_view_core.h"
 #include "net/url_request/url_fetcher_delegate.h"
 
@@ -27,15 +28,9 @@
     : public net::URLFetcherDelegate,
       public base::SupportsWeakPtr<ContextualSearchDelegate> {
  public:
-  typedef base::Callback<void(bool,
-                              int,
-                              const std::string&,
-                              const std::string&,
-                              const std::string&,
-                              bool,
-                              int,
-                              int)> SearchTermResolutionCallback;
   typedef base::Callback<void(const std::string&)> SurroundingTextCallback;
+  typedef base::Callback<void(const ResolvedSearchTerm&)>
+      SearchTermResolutionCallback;
   typedef base::Callback<
       void(const base::string16&, int, int)>
       HandleSurroundingsCallback;
@@ -76,6 +71,12 @@
   // text has been gathered.
   void ContinueSearchTermResolutionRequest();
 
+  // Gets the target language for translation purposes for this user.
+  std::string GetTargetLanguage();
+
+  // Returns the accept languages preference string.
+  std::string GetAcceptLanguages();
+
   // For testing.
   void set_context_for_testing(ContextualSearchContext* context) {
     context_.reset(context);
@@ -97,7 +98,7 @@
   FRIEND_TEST_ALL_PREFIXES(ContextualSearchDelegateTest,
                            SurroundingTextForIcingNegativeLimit);
   FRIEND_TEST_ALL_PREFIXES(ContextualSearchDelegateTest,
-                           DecodeSearchTermsFromJsonResponse);
+                           DecodeSearchTermFromJsonResponse);
 
   // net::URLFetcherDelegate:
   void OnURLFetchComplete(const net::URLFetcher* source) override;
@@ -152,13 +153,14 @@
                       TemplateURLService* template_url_service);
 
   // Decodes the given json response string and extracts parameters.
-  void DecodeSearchTermsFromJsonResponse(const std::string& response,
-                                         std::string* search_term,
-                                         std::string* display_text,
-                                         std::string* alternate_term,
-                                         std::string* prevent_preload,
-                                         int* mention_start,
-                                         int* mention_end);
+  void DecodeSearchTermFromJsonResponse(const std::string& response,
+                                        std::string* search_term,
+                                        std::string* display_text,
+                                        std::string* alternate_term,
+                                        std::string* prevent_preload,
+                                        int* mention_start,
+                                        int* mention_end,
+                                        std::string* context_language);
 
   void ExtractMentionsStartEnd(const base::ListValue& mentions_list,
                                int* startResult,
diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc b/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc
index 0dca49fa..7f706961 100644
--- a/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc
+++ b/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/android/contextualsearch/contextual_search_context.h"
+#include "chrome/browser/android/contextualsearch/resolved_search_term.h"
 #include "components/search_engines/template_url_service.h"
 #include "net/base/escape.h"
 #include "net/url_request/test_url_fetcher_factory.h"
@@ -50,6 +51,7 @@
     response_code_ = -1;
     search_term_ = "invalid";
     display_text_ = "unknown";
+    context_language_ = "";
   }
 
   TemplateURLService* CreateTemplateURLService() {
@@ -137,27 +139,23 @@
   std::string after_text() { return after_text_; }
   int start_adjust() { return start_adjust_; }
   int end_adjust() { return end_adjust_; }
+  std::string context_language() { return context_language_; }
 
   // The delegate under test.
   scoped_ptr<ContextualSearchDelegate> delegate_;
 
  private:
-  void recordSearchTermResolutionResponse(bool is_invalid,
-                                          int response_code,
-                                          const std::string& search_term,
-                                          const std::string& display_text,
-                                          const std::string& alternate_term,
-                                          bool prevent_preload,
-                                          int start_adjust,
-                                          int end_adjust) {
-    is_invalid_ = is_invalid;
-    response_code_ = response_code;
-    search_term_ = search_term;
-    display_text_ = display_text;
-    alternate_term_ = alternate_term;
-    prevent_preload_ = prevent_preload;
-    start_adjust_ = start_adjust;
-    end_adjust_ = end_adjust;
+  void recordSearchTermResolutionResponse(
+      const ResolvedSearchTerm& resolved_search_term) {
+    is_invalid_ = resolved_search_term.is_invalid;
+    response_code_ = resolved_search_term.response_code;
+    search_term_ = resolved_search_term.search_term;
+    display_text_ = resolved_search_term.display_text;
+    alternate_term_ = resolved_search_term.alternate_term;
+    prevent_preload_ = resolved_search_term.prevent_preload;
+    start_adjust_ = resolved_search_term.selection_start_adjust;
+    end_adjust_ = resolved_search_term.selection_end_adjust;
+    context_language_ = resolved_search_term.context_language;
   }
 
   void recordSurroundingText(const std::string& after_text) {
@@ -180,6 +178,7 @@
   int start_adjust_;
   int end_adjust_;
   std::string after_text_;
+  std::string context_language_;
 
   base::MessageLoopForIO io_message_loop_;
   net::TestURLFetcherFactory test_factory_;
@@ -452,7 +451,7 @@
   EXPECT_EQ(base::ASCIIToUTF16("Barack Obama"), result);
 }
 
-TEST_F(ContextualSearchDelegateTest, DecodeSearchTermsFromJsonResponse) {
+TEST_F(ContextualSearchDelegateTest, DecodeSearchTermFromJsonResponse) {
   std::string json_with_escape =
       ")]}'\n"
       "{\"mid\":\"/m/02mjmr\", \"search_term\":\"obama\","
@@ -465,12 +464,31 @@
   std::string prevent_preload;
   int mention_start;
   int mention_end;
-  delegate_->DecodeSearchTermsFromJsonResponse(json_with_escape, &search_term,
-                                               &display_text, &alternate_term,
-                                               &prevent_preload, &mention_start,
-                                               &mention_end);
+  std::string context_language;
+  delegate_->DecodeSearchTermFromJsonResponse(
+      json_with_escape, &search_term, &display_text, &alternate_term,
+      &prevent_preload, &mention_start, &mention_end, &context_language);
   EXPECT_EQ("obama", search_term);
   EXPECT_EQ("Barack Obama", display_text);
   EXPECT_EQ("barack obama", alternate_term);
   EXPECT_EQ("", prevent_preload);
+  EXPECT_EQ("", context_language);
+}
+
+TEST_F(ContextualSearchDelegateTest, ResponseWithLanguage) {
+  CreateDefaultSearchContextAndRequestSearchTerm();
+  fetcher()->set_response_code(200);
+  fetcher()->SetResponseString(
+      "{\"mid\":\"/m/02mjmr\",\"search_term\":\"obama\","
+      "\"mentions\":[0,15],\"prevent_preload\":\"1\", "
+      "\"lang\":\"de\"}");
+  fetcher()->delegate()->OnURLFetchComplete(fetcher());
+
+  EXPECT_FALSE(is_invalid());
+  EXPECT_EQ(200, response_code());
+  EXPECT_EQ("obama", search_term());
+  EXPECT_EQ("obama", display_text());
+  EXPECT_TRUE(do_prevent_preload());
+  EXPECT_TRUE(DoesRequestContainOurSpecificBasePage());
+  EXPECT_EQ("de", context_language());
 }
diff --git a/chrome/browser/android/contextualsearch/contextual_search_manager.cc b/chrome/browser/android/contextualsearch/contextual_search_manager.cc
index c8b41ab..3e1a640d 100644
--- a/chrome/browser/android/contextualsearch/contextual_search_manager.cc
+++ b/chrome/browser/android/contextualsearch/contextual_search_manager.cc
@@ -11,6 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/contextualsearch/contextual_search_delegate.h"
+#include "chrome/browser/android/contextualsearch/resolved_search_term.h"
 #include "chrome/browser/android/tab_android.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
@@ -89,27 +90,45 @@
                                           may_send_base_page_url);
 }
 
+base::android::ScopedJavaLocalRef<jstring>
+ContextualSearchManager::GetTargetLanguage(JNIEnv* env, jobject obj) {
+  std::string target_language = delegate_->GetTargetLanguage();
+  base::android::ScopedJavaLocalRef<jstring> j_target_language =
+      base::android::ConvertUTF8ToJavaString(env, target_language.c_str());
+  return j_target_language;
+}
+
+base::android::ScopedJavaLocalRef<jstring>
+ContextualSearchManager::GetAcceptLanguages(JNIEnv* env, jobject obj) {
+  std::string accept_languages = delegate_->GetAcceptLanguages();
+  base::android::ScopedJavaLocalRef<jstring> j_accept_languages =
+      base::android::ConvertUTF8ToJavaString(env, accept_languages.c_str());
+  return j_accept_languages;
+}
+
 void ContextualSearchManager::OnSearchTermResolutionResponse(
-    bool is_invalid,
-    int response_code,
-    const std::string& search_term,
-    const std::string& display_text,
-    const std::string& alternate_term,
-    bool prevent_preload,
-    int selection_start_adjust,
-    int selection_end_adjust) {
+    const ResolvedSearchTerm& resolved_search_term) {
   // Notify the Java UX of the result.
   JNIEnv* env = base::android::AttachCurrentThread();
   base::android::ScopedJavaLocalRef<jstring> j_search_term =
-      base::android::ConvertUTF8ToJavaString(env, search_term.c_str());
+      base::android::ConvertUTF8ToJavaString(
+          env, resolved_search_term.search_term.c_str());
   base::android::ScopedJavaLocalRef<jstring> j_display_text =
-      base::android::ConvertUTF8ToJavaString(env, display_text.c_str());
+      base::android::ConvertUTF8ToJavaString(
+          env, resolved_search_term.display_text.c_str());
   base::android::ScopedJavaLocalRef<jstring> j_alternate_term =
-      base::android::ConvertUTF8ToJavaString(env, alternate_term.c_str());
+      base::android::ConvertUTF8ToJavaString(
+          env, resolved_search_term.alternate_term.c_str());
+  base::android::ScopedJavaLocalRef<jstring> j_context_language =
+      base::android::ConvertUTF8ToJavaString(
+          env, resolved_search_term.context_language.c_str());
   Java_ContextualSearchManager_onSearchTermResolutionResponse(
-      env, java_manager_.obj(), is_invalid, response_code, j_search_term.obj(),
-      j_display_text.obj(), j_alternate_term.obj(), prevent_preload,
-      selection_start_adjust, selection_end_adjust);
+      env, java_manager_.obj(), resolved_search_term.is_invalid,
+      resolved_search_term.response_code, j_search_term.obj(),
+      j_display_text.obj(), j_alternate_term.obj(),
+      resolved_search_term.prevent_preload,
+      resolved_search_term.selection_start_adjust,
+      resolved_search_term.selection_end_adjust, j_context_language.obj());
 }
 
 void ContextualSearchManager::OnSurroundingTextAvailable(
diff --git a/chrome/browser/android/contextualsearch/contextual_search_manager.h b/chrome/browser/android/contextualsearch/contextual_search_manager.h
index 08a2e3d..a29dc63 100644
--- a/chrome/browser/android/contextualsearch/contextual_search_manager.h
+++ b/chrome/browser/android/contextualsearch/contextual_search_manager.h
@@ -46,16 +46,17 @@
                              jobject j_base_content_view_core,
                              jboolean j_may_send_base_page_url);
 
+  // Gets the target language for translation purposes.
+  base::android::ScopedJavaLocalRef<jstring> GetTargetLanguage(JNIEnv* env,
+                                                               jobject obj);
+
+  // Gets the accept-languages preference string.
+  base::android::ScopedJavaLocalRef<jstring> GetAcceptLanguages(JNIEnv* env,
+                                                                jobject obj);
+
  private:
-  // TODO(donnd): encapsulate these response parameters?
-  void OnSearchTermResolutionResponse(bool is_invalid,
-                                      int response_code,
-                                      const std::string& search_term,
-                                      const std::string& display_text,
-                                      const std::string& alternate_term,
-                                      bool prevent_preload,
-                                      int selection_start_adjust,
-                                      int selection_end_adjust);
+  void OnSearchTermResolutionResponse(
+      const ResolvedSearchTerm& resolved_search_term);
 
   // Calls back to Java with the surrounding text to be displayed.
   void OnSurroundingTextAvailable(const std::string& after_text);
diff --git a/chrome/browser/android/contextualsearch/resolved_search_term.cc b/chrome/browser/android/contextualsearch/resolved_search_term.cc
new file mode 100644
index 0000000..7dbae11
--- /dev/null
+++ b/chrome/browser/android/contextualsearch/resolved_search_term.cc
@@ -0,0 +1,26 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/contextualsearch/resolved_search_term.h"
+
+ResolvedSearchTerm::ResolvedSearchTerm(bool is_invalid,
+                                       int response_code,
+                                       const std::string& search_term,
+                                       const std::string& display_text,
+                                       const std::string& alternate_term,
+                                       bool prevent_preload,
+                                       int selection_start_adjust,
+                                       int selection_end_adjust,
+                                       const std::string& context_language)
+    : is_invalid(is_invalid),
+      response_code(response_code),
+      search_term(search_term),
+      display_text(display_text),
+      alternate_term(alternate_term),
+      prevent_preload(prevent_preload),
+      selection_start_adjust(selection_start_adjust),
+      selection_end_adjust(selection_end_adjust),
+      context_language(context_language) {}
+
+ResolvedSearchTerm::~ResolvedSearchTerm() {}
diff --git a/chrome/browser/android/contextualsearch/resolved_search_term.h b/chrome/browser/android/contextualsearch/resolved_search_term.h
new file mode 100644
index 0000000..042a37a
--- /dev/null
+++ b/chrome/browser/android/contextualsearch/resolved_search_term.h
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ANDROID_CONTEXTUALSEARCH_RESOLVED_SEARCH_TERM_H_
+#define CHROME_BROWSER_ANDROID_CONTEXTUALSEARCH_RESOLVED_SEARCH_TERM_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+
+// Encapsulates the various parts of a Resolved Search Term, which tells
+// Contextual Search what to search for and how that term appears in the
+// surrounding text.
+struct ResolvedSearchTerm {
+ public:
+  ResolvedSearchTerm(bool is_invalid,
+                     int response_code,
+                     const std::string& search_term,
+                     const std::string& display_text,
+                     const std::string& alternate_term,
+                     bool prevent_preload,
+                     int selection_start_adjust,
+                     int selection_end_adjust,
+                     const std::string& context_language);
+  ~ResolvedSearchTerm();
+
+  const bool is_invalid;
+  const int response_code;
+  const std::string& search_term;
+  const std::string& display_text;
+  const std::string& alternate_term;
+  const bool prevent_preload;
+  const int selection_start_adjust;
+  const int selection_end_adjust;
+  const std::string& context_language;
+
+  DISALLOW_COPY_AND_ASSIGN(ResolvedSearchTerm);
+};
+
+#endif  // CHROME_BROWSER_ANDROID_CONTEXTUALSEARCH_RESOLVED_SEARCH_TERM_H_
diff --git a/chrome/browser/apps/service_worker_browsertest.cc b/chrome/browser/apps/service_worker_browsertest.cc
new file mode 100644
index 0000000..d5ce4d5
--- /dev/null
+++ b/chrome/browser/apps/service_worker_browsertest.cc
@@ -0,0 +1,11 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/apps/app_browsertest_util.h"
+
+using ServiceWorkerAppTest = extensions::PlatformAppBrowserTest;
+
+IN_PROC_BROWSER_TEST_F(ServiceWorkerAppTest, RegisterAndPostMessage) {
+  ASSERT_TRUE(RunPlatformAppTest("platform_apps/service_worker")) << message_;
+}
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 9ad6608..7d218e7 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -129,6 +129,7 @@
         <include name="IDR_MD_DOWNLOADS_CONSTANTS_HTML" file="resources\md_downloads\constants.html" type="BINDATA" />
         <include name="IDR_MD_DOWNLOADS_CONSTANTS_JS" file="resources\md_downloads\constants.js" type="BINDATA" />
         <include name="IDR_MD_DOWNLOADS_CRISPER_JS" file="resources\md_downloads\crisper.js" flattenhtml="true" type="BINDATA" />
+        <include name="IDR_MD_DOWNLOADS_DOWNLOADS_JS" file="resources\md_downloads\downloads.js" type="BINDATA" />
         <include name="IDR_MD_DOWNLOADS_ITEM_CSS" file="resources\md_downloads\item.css" type="BINDATA" flattenhtml="true" />
         <include name="IDR_MD_DOWNLOADS_ITEM_HTML" file="resources\md_downloads\item.html" type="BINDATA" />
         <include name="IDR_MD_DOWNLOADS_ITEM_JS" file="resources\md_downloads\item.js" type="BINDATA" />
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 372d0ee4..cb3ca1d 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -117,7 +117,7 @@
 #include "components/nacl/browser/nacl_browser.h"
 #include "components/rappor/rappor_service.h"
 #include "components/signin/core/common/profile_management_switches.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "components/tracing/tracing_switches.h"
 #include "components/translate/content/browser/browser_cld_utils.h"
 #include "components/translate/content/common/cld_data_source.h"
diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc
index 24b37c7..1090f350 100644
--- a/chrome/browser/chrome_browser_main_linux.cc
+++ b/chrome/browser/chrome_browser_main_linux.cc
@@ -10,6 +10,8 @@
 #include "chrome/grit/chromium_strings.h"
 #include "components/crash/content/app/breakpad_linux.h"
 #include "components/metrics/metrics_service.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/dbus_thread_manager_linux.h"
 #include "media/audio/audio_manager.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -62,3 +64,22 @@
   g_browser_process->metrics_service()->RecordBreakpadRegistration(
       breakpad::IsCrashReporterEnabled());
 }
+
+void ChromeBrowserMainPartsLinux::PostMainMessageLoopStart() {
+#if !defined(OS_CHROMEOS)
+  bluez::DBusThreadManagerLinux::Initialize();
+  bluez::BluezDBusManager::Initialize(
+      bluez::DBusThreadManagerLinux::Get()->GetSystemBus(), false);
+#endif
+
+  ChromeBrowserMainPartsPosix::PostMainMessageLoopStart();
+}
+
+void ChromeBrowserMainPartsLinux::PostDestroyThreads() {
+#if !defined(OS_CHROMEOS)
+  bluez::BluezDBusManager::Shutdown();
+  bluez::DBusThreadManagerLinux::Shutdown();
+#endif
+
+  ChromeBrowserMainPartsPosix::PostDestroyThreads();
+}
diff --git a/chrome/browser/chrome_browser_main_linux.h b/chrome/browser/chrome_browser_main_linux.h
index aa9ff2f..ec664c7 100644
--- a/chrome/browser/chrome_browser_main_linux.h
+++ b/chrome/browser/chrome_browser_main_linux.h
@@ -20,6 +20,8 @@
   void ToolkitInitialized() override;
   void PreProfileInit() override;
   void PostProfileInit() override;
+  void PostMainMessageLoopStart() override;
+  void PostDestroyThreads() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsLinux);
diff --git a/chrome/browser/chromeos/app_mode/app_session.cc b/chrome/browser/chromeos/app_mode/app_session.cc
new file mode 100644
index 0000000..9c4804e
--- /dev/null
+++ b/chrome/browser/chromeos/app_mode/app_session.cc
@@ -0,0 +1,269 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/app_mode/app_session.h"
+
+#include <errno.h>
+#include <signal.h>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/lazy_instance.h"
+#include "base/message_loop/message_loop.h"
+#include "base/prefs/pref_service.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_app_update_service.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler.h"
+#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_list_observer.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/pref_names.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/power_manager_client.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "components/user_manager/user_manager.h"
+#include "content/public/browser/browser_child_process_host_iterator.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/child_process_data.h"
+#include "content/public/browser/plugin_service.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/process_type.h"
+#include "content/public/common/webplugininfo.h"
+#include "extensions/browser/app_window/app_window.h"
+#include "extensions/browser/app_window/app_window_registry.h"
+#include "extensions/browser/guest_view/web_view/web_view_guest.h"
+
+using extensions::AppWindow;
+using extensions::AppWindowRegistry;
+
+namespace chromeos {
+
+namespace {
+
+bool IsPepperPlugin(const base::FilePath& plugin_path) {
+  content::WebPluginInfo plugin_info;
+  return content::PluginService::GetInstance()->GetPluginInfoByPath(
+             plugin_path, &plugin_info) &&
+         plugin_info.is_pepper_plugin();
+}
+
+void RebootDevice() {
+  DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
+}
+
+// Sends a SIGFPE signal to plugin subprocesses that matches |child_ids|
+// to trigger a dump.
+void DumpPluginProcessOnIOThread(const std::set<int>& child_ids) {
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+
+  bool dump_requested = false;
+
+  content::BrowserChildProcessHostIterator iter(
+      content::PROCESS_TYPE_PPAPI_PLUGIN);
+  while (!iter.Done()) {
+    const content::ChildProcessData& data = iter.GetData();
+    if (child_ids.count(data.id) == 1) {
+      // Send a signal to dump the plugin process.
+      if (kill(data.handle, SIGFPE) == 0) {
+        dump_requested = true;
+      } else {
+        LOG(WARNING) << "Failed to send SIGFPE to plugin process"
+                     << ", errno=" << errno
+                     << ", pid=" << data.handle
+                     << ", type=" << data.process_type
+                     << ", name=" << data.name;
+      }
+    }
+    ++iter;
+  }
+
+  // Wait a bit to let dump finish (if requested) before rebooting the device.
+  const int kDumpWaitSeconds = 10;
+  content::BrowserThread::PostDelayedTask(
+      content::BrowserThread::UI,
+      FROM_HERE,
+      base::Bind(&RebootDevice),
+      base::TimeDelta::FromSeconds(dump_requested ? kDumpWaitSeconds : 0));
+}
+
+}  // namespace
+
+class AppSession::AppWindowHandler : public AppWindowRegistry::Observer {
+ public:
+  explicit AppWindowHandler(AppSession* app_session)
+      : app_session_(app_session) {}
+  ~AppWindowHandler() override {}
+
+  void Init(Profile* profile, const std::string& app_id) {
+    DCHECK(!window_registry_);
+    window_registry_ = AppWindowRegistry::Get(profile);
+    if (window_registry_)
+      window_registry_->AddObserver(this);
+    app_id_ = app_id;
+  }
+
+ private:
+  // extensions::AppWindowRegistry::Observer overrides:
+  void OnAppWindowAdded(AppWindow* app_window) override {
+    app_session_->OnAppWindowAdded(app_window);
+  }
+
+  void OnAppWindowRemoved(AppWindow* app_window) override {
+    if (window_registry_->GetAppWindowsForApp(app_id_).empty()) {
+      if (DemoAppLauncher::IsDemoAppSession(
+              user_manager::UserManager::Get()->GetActiveUser()->email())) {
+        // If we were in demo mode, we disabled all our network technologies,
+        // re-enable them.
+        NetworkStateHandler* handler =
+            NetworkHandler::Get()->network_state_handler();
+        handler->SetTechnologyEnabled(
+            NetworkTypePattern::NonVirtual(),
+            true,
+            chromeos::network_handler::ErrorCallback());
+      }
+      app_session_->OnLastAppWindowClosed();
+      window_registry_->RemoveObserver(this);
+    }
+  }
+
+  AppSession* const app_session_;
+  AppWindowRegistry* window_registry_ = nullptr;
+  std::string app_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(AppWindowHandler);
+};
+
+class AppSession::BrowserWindowHandler : public chrome::BrowserListObserver {
+ public:
+  BrowserWindowHandler() {
+    BrowserList::AddObserver(this);
+  }
+  ~BrowserWindowHandler() override { BrowserList::RemoveObserver(this); }
+
+ private:
+  void HandleBrowser(Browser* browser) {
+    content::WebContents* active_tab =
+        browser->tab_strip_model()->GetActiveWebContents();
+    std::string url_string =
+        active_tab ? active_tab->GetURL().spec() : std::string();
+    LOG(WARNING) << "Browser opened in kiosk session"
+                 << ", url=" << url_string;
+
+    browser->window()->Close();
+  }
+
+  // chrome::BrowserListObserver overrides:
+  void OnBrowserAdded(Browser* browser) override {
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&BrowserWindowHandler::HandleBrowser,
+                   base::Unretained(this),  // LazyInstance, always valid
+                   browser));
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(BrowserWindowHandler);
+};
+
+AppSession::AppSession() {}
+AppSession::~AppSession() {}
+
+void AppSession::Init(Profile* profile, const std::string& app_id) {
+  app_window_handler_.reset(new AppWindowHandler(this));
+  app_window_handler_->Init(profile, app_id);
+
+  browser_window_handler_.reset(new BrowserWindowHandler);
+
+  plugin_handler_.reset(new KioskSessionPluginHandler(this));
+
+  // For a demo app, we don't need to either setup the update service or
+  // the idle app name notification.
+  if (DemoAppLauncher::IsDemoAppSession(
+          user_manager::UserManager::Get()->GetActiveUser()->email()))
+    return;
+
+  // Set the app_id for the current instance of KioskAppUpdateService.
+  KioskAppUpdateService* update_service =
+      KioskAppUpdateServiceFactory::GetForProfile(profile);
+  DCHECK(update_service);
+  if (update_service)
+    update_service->Init(app_id);
+
+  // Start to monitor external update from usb stick.
+  KioskAppManager::Get()->MonitorKioskExternalUpdate();
+
+  // If the device is not enterprise managed, set prefs to reboot after update
+  // and create a user security message which shows the user the application
+  // name and author after some idle timeout.
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
+  if (!connector->IsEnterpriseManaged()) {
+    PrefService* local_state = g_browser_process->local_state();
+    local_state->SetBoolean(prefs::kRebootAfterUpdate, true);
+    KioskModeIdleAppNameNotification::Initialize();
+  }
+}
+
+void AppSession::OnAppWindowAdded(AppWindow* app_window) {
+  if (is_shutting_down_)
+    return;
+
+  plugin_handler_->Observe(app_window->web_contents());
+}
+
+void AppSession::OnGuestAdded(content::WebContents* guest_web_contents) {
+  // Bail if the session is shutting down.
+  if (is_shutting_down_)
+    return;
+
+  // Bail if the guest is not a WebViewGuest.
+  if (!extensions::WebViewGuest::FromWebContents(guest_web_contents))
+    return;
+
+  plugin_handler_->Observe(guest_web_contents);
+}
+
+void AppSession::OnLastAppWindowClosed() {
+  if (is_shutting_down_)
+    return;
+  is_shutting_down_ = true;
+
+  chrome::AttemptUserExit();
+}
+
+bool AppSession::ShouldHandlePlugin(const base::FilePath& plugin_path) const {
+  // Note that BrowserChildProcessHostIterator in DumpPluginProcessOnIOThread
+  // also needs to be updated when adding more plugin types here.
+  return IsPepperPlugin(plugin_path);
+}
+
+void AppSession::OnPluginCrashed(const base::FilePath& plugin_path) {
+  if (is_shutting_down_)
+    return;
+  is_shutting_down_ = true;
+
+  LOG(ERROR) << "Reboot due to plugin crash, path=" << plugin_path.value();
+  RebootDevice();
+}
+
+void AppSession::OnPluginHung(const std::set<int>& hung_plugins) {
+  if (is_shutting_down_)
+    return;
+  is_shutting_down_ = true;
+
+  LOG(ERROR) << "Plugin hung detected. Dump and reboot.";
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&DumpPluginProcessOnIOThread, hung_plugins));
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/app_mode/app_session.h b/chrome/browser/chromeos/app_mode/app_session.h
new file mode 100644
index 0000000..facc40e
--- /dev/null
+++ b/chrome/browser/chromeos/app_mode/app_session.h
@@ -0,0 +1,69 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_H_
+#define CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler_delegate.h"
+
+class Profile;
+
+namespace content {
+class WebContents;
+}
+
+namespace extensions {
+class AppWindow;
+}
+
+namespace chromeos {
+
+class KioskSessionPluginHandler;
+
+// AppSession maintains a kiosk session and handles its lifetime.
+class AppSession : public KioskSessionPluginHandlerDelegate {
+ public:
+  AppSession();
+  ~AppSession() override;
+
+  // Initializes an app session.
+  void Init(Profile* profile, const std::string& app_id);
+
+  // Invoked when GuestViewManager adds a guest web contents.
+  void OnGuestAdded(content::WebContents* guest_web_contents);
+
+ private:
+  // AppWindowHandler watches for app window and exits the session when the
+  // last window of a given app is closed.
+  class AppWindowHandler;
+
+  // BrowserWindowHandler monitors Browser object being created during
+  // a kiosk session, log info such as URL so that the code path could be
+  // fixed and closes the just opened browser window.
+  class BrowserWindowHandler;
+
+  void OnAppWindowAdded(extensions::AppWindow* app_window);
+  void OnLastAppWindowClosed();
+
+  // KioskSessionPluginHandlerDelegate
+  bool ShouldHandlePlugin(const base::FilePath& plugin_path) const override;
+  void OnPluginCrashed(const base::FilePath& plugin_path) override;
+  void OnPluginHung(const std::set<int>& hung_plugins) override;
+
+  bool is_shutting_down_ = false;
+
+  scoped_ptr<AppWindowHandler> app_window_handler_;
+  scoped_ptr<BrowserWindowHandler> browser_window_handler_;
+  scoped_ptr<KioskSessionPluginHandler> plugin_handler_;
+
+  DISALLOW_COPY_AND_ASSIGN(AppSession);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_H_
diff --git a/chrome/browser/chromeos/app_mode/app_session_lifetime.cc b/chrome/browser/chromeos/app_mode/app_session_lifetime.cc
deleted file mode 100644
index 741a1c1..0000000
--- a/chrome/browser/chromeos/app_mode/app_session_lifetime.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/message_loop/message_loop.h"
-#include "base/prefs/pref_service.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
-#include "chrome/browser/chromeos/app_mode/kiosk_app_update_service.h"
-#include "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h"
-#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
-#include "chrome/browser/lifetime/application_lifetime.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_list_observer.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/pref_names.h"
-#include "chromeos/network/network_state.h"
-#include "chromeos/network/network_state_handler.h"
-#include "components/user_manager/user_manager.h"
-#include "content/public/browser/web_contents.h"
-#include "extensions/browser/app_window/app_window.h"
-#include "extensions/browser/app_window/app_window_registry.h"
-
-using extensions::AppWindow;
-using extensions::AppWindowRegistry;
-
-namespace chromeos {
-
-namespace {
-
-// AppWindowHandler watches for app window and exits the session when the
-// last window of a given app is closed.
-class AppWindowHandler : public AppWindowRegistry::Observer {
- public:
-  AppWindowHandler() : window_registry_(NULL) {}
-  ~AppWindowHandler() override {}
-
-  void Init(Profile* profile, const std::string& app_id) {
-    DCHECK(!window_registry_);
-    window_registry_ = AppWindowRegistry::Get(profile);
-    if (window_registry_)
-      window_registry_->AddObserver(this);
-    app_id_ = app_id;
-  }
-
- private:
-  // extensions::AppWindowRegistry::Observer overrides:
-  void OnAppWindowRemoved(AppWindow* app_window) override {
-    if (window_registry_->GetAppWindowsForApp(app_id_).empty()) {
-      if (DemoAppLauncher::IsDemoAppSession(
-              user_manager::UserManager::Get()->GetActiveUser()->email())) {
-        // If we were in demo mode, we disabled all our network technologies,
-        // re-enable them.
-        NetworkStateHandler* handler =
-            NetworkHandler::Get()->network_state_handler();
-        handler->SetTechnologyEnabled(
-            NetworkTypePattern::NonVirtual(),
-            true,
-            chromeos::network_handler::ErrorCallback());
-      }
-      chrome::AttemptUserExit();
-      window_registry_->RemoveObserver(this);
-    }
-  }
-
-  AppWindowRegistry* window_registry_;
-  std::string app_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppWindowHandler);
-};
-
-base::LazyInstance<AppWindowHandler> app_window_handler
-    = LAZY_INSTANCE_INITIALIZER;
-
-// BrowserWindowHandler monitors Browser object being created during
-// a kiosk session, log info such as URL so that the code path could be
-// fixed and closes the just opened browser window.
-class BrowserWindowHandler : public chrome::BrowserListObserver {
- public:
-  BrowserWindowHandler() {
-    BrowserList::AddObserver(this);
-  }
-  ~BrowserWindowHandler() override { BrowserList::RemoveObserver(this); }
-
- private:
-  void HandleBrowser(Browser* browser) {
-    content::WebContents* active_tab =
-        browser->tab_strip_model()->GetActiveWebContents();
-    std::string url_string =
-        active_tab ? active_tab->GetURL().spec() : std::string();
-    LOG(WARNING) << "Browser opened in kiosk session"
-                 << ", url=" << url_string;
-
-    browser->window()->Close();
-  }
-
-  // chrome::BrowserListObserver overrides:
-  void OnBrowserAdded(Browser* browser) override {
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&BrowserWindowHandler::HandleBrowser,
-                   base::Unretained(this),  // LazyInstance, always valid
-                   browser));
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(BrowserWindowHandler);
-};
-
-base::LazyInstance<BrowserWindowHandler> browser_window_handler
-    = LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-void InitAppSession(Profile* profile, const std::string& app_id) {
-  // Binds the session lifetime with app window counts.
-  CHECK(app_window_handler == NULL);
-  app_window_handler.Get().Init(profile, app_id);
-
-  CHECK(browser_window_handler == NULL);
-  browser_window_handler.Get();
-
-  // For a demo app, we don't need to either setup the update service or
-  // the idle app name notification.
-  if (DemoAppLauncher::IsDemoAppSession(
-          user_manager::UserManager::Get()->GetActiveUser()->email()))
-    return;
-
-  // Set the app_id for the current instance of KioskAppUpdateService.
-  KioskAppUpdateService* update_service =
-      KioskAppUpdateServiceFactory::GetForProfile(profile);
-  DCHECK(update_service);
-  if (update_service)
-    update_service->Init(app_id);
-
-  // Start to monitor external update from usb stick.
-  KioskAppManager::Get()->MonitorKioskExternalUpdate();
-
-  // If the device is not enterprise managed, set prefs to reboot after update
-  // and create a user security message which shows the user the application
-  // name and author after some idle timeout.
-  policy::BrowserPolicyConnectorChromeOS* connector =
-      g_browser_process->platform_part()->browser_policy_connector_chromeos();
-  if (!connector->IsEnterpriseManaged()) {
-    PrefService* local_state = g_browser_process->local_state();
-    local_state->SetBoolean(prefs::kRebootAfterUpdate, true);
-    KioskModeIdleAppNameNotification::Initialize();
-  }
-}
-
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/app_mode/app_session_lifetime.h b/chrome/browser/chromeos/app_mode/app_session_lifetime.h
deleted file mode 100644
index 4472a200..0000000
--- a/chrome/browser/chromeos/app_mode/app_session_lifetime.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_LIFETIME_H_
-#define CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_LIFETIME_H_
-
-#include <string>
-
-class Profile;
-
-namespace chromeos {
-
-// Initializes an app session.
-void InitAppSession(Profile* profile, const std::string& app_id);
-
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_LIFETIME_H_
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
index 0dd9f22d..7bca13ed 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -19,6 +19,7 @@
 #include "base/stl_util.h"
 #include "base/sys_info.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/app_mode/app_session.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_data.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_external_loader.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
@@ -207,6 +208,14 @@
   currently_auto_launched_with_zero_delay_app_ = app_id;
 }
 
+void KioskAppManager::InitSession(Profile* profile,
+                                   const std::string& app_id) {
+  LOG_IF(FATAL, app_session_) << "Kiosk session is already initialized.";
+
+  app_session_.reset(new AppSession);
+  app_session_->Init(profile, app_id);
+}
+
 void KioskAppManager::EnableConsumerKioskAutoLaunch(
     const KioskAppManager::EnableKioskAutoLaunchCallback& callback) {
   policy::BrowserPolicyConnectorChromeOS* connector =
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
index 90e020a..13d8da3 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
@@ -34,6 +34,7 @@
 
 namespace chromeos {
 
+class AppSession;
 class KioskAppData;
 class KioskAppExternalLoader;
 class KioskAppManagerObserver;
@@ -220,6 +221,11 @@
   // kiosk apps that are immediately auto-launched on startup.
   void SetAppWasAutoLaunchedWithZeroDelay(const std::string& app_id);
 
+  // Initialize |app_session_|.
+  void InitSession(Profile* profile, const std::string& app_id);
+
+  AppSession* app_session() { return app_session_.get(); }
+
  private:
   friend struct base::DefaultLazyInstanceTraits<KioskAppManager>;
   friend struct base::DefaultDeleter<KioskAppManager>;
@@ -306,6 +312,8 @@
   bool secondary_app_external_loader_created_;
   base::WeakPtr<KioskAppExternalLoader> secondary_app_external_loader_;
 
+  scoped_ptr<AppSession> app_session_;
+
   DISALLOW_COPY_AND_ASSIGN(KioskAppManager);
 };
 
diff --git a/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler.cc b/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler.cc
new file mode 100644
index 0000000..f73bb93
--- /dev/null
+++ b/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler.cc
@@ -0,0 +1,129 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler_delegate.h"
+#include "content/public/browser/web_contents_observer.h"
+
+namespace chromeos {
+
+namespace {
+
+// Seconds to wait after a plugin hung is detected.
+const int kHungWaitSeconds = 20;
+
+}  // namespace
+
+class KioskSessionPluginHandler::Observer
+    : public content::WebContentsObserver {
+ public:
+  Observer(content::WebContents* contents, KioskSessionPluginHandler* owner);
+  ~Observer() override;
+
+ private:
+  void OnHungWaitTimer();
+
+  // content::WebContentsObserver
+  void PluginCrashed(const base::FilePath& plugin_path,
+                     base::ProcessId plugin_pid) override;
+  void PluginHungStatusChanged(int plugin_child_id,
+                               const base::FilePath& plugin_path,
+                               bool is_hung) override;
+  void WebContentsDestroyed() override;
+
+  KioskSessionPluginHandler* const owner_;
+  std::set<int> hung_plugins_;
+  base::OneShotTimer hung_wait_timer_;
+
+  DISALLOW_COPY_AND_ASSIGN(Observer);
+};
+
+KioskSessionPluginHandler::Observer::Observer(content::WebContents* contents,
+                                              KioskSessionPluginHandler* owner)
+    : content::WebContentsObserver(contents),
+      owner_(owner) {
+}
+
+KioskSessionPluginHandler::Observer::~Observer() {}
+
+void KioskSessionPluginHandler::Observer::OnHungWaitTimer() {
+  owner_->OnPluginHung(hung_plugins_);
+}
+
+void KioskSessionPluginHandler::Observer::PluginCrashed(
+    const base::FilePath& plugin_path,
+    base::ProcessId plugin_pid) {
+  if (!owner_->delegate_->ShouldHandlePlugin(plugin_path))
+    return;
+
+  owner_->OnPluginCrashed(plugin_path);
+}
+
+void KioskSessionPluginHandler::Observer::PluginHungStatusChanged(
+    int plugin_child_id,
+    const base::FilePath& plugin_path,
+    bool is_hung) {
+  if (!owner_->delegate_->ShouldHandlePlugin(plugin_path))
+    return;
+
+  if (is_hung)
+    hung_plugins_.insert(plugin_child_id);
+  else
+    hung_plugins_.erase(plugin_child_id);
+
+  if (!hung_plugins_.empty()) {
+    if (!hung_wait_timer_.IsRunning()) {
+      hung_wait_timer_.Start(
+          FROM_HERE, base::TimeDelta::FromSeconds(kHungWaitSeconds), this,
+          &KioskSessionPluginHandler::Observer::OnHungWaitTimer);
+    }
+  } else {
+    hung_wait_timer_.Stop();
+  }
+}
+
+void KioskSessionPluginHandler::Observer::WebContentsDestroyed() {
+  owner_->OnWebContentsDestroyed(this);
+}
+
+KioskSessionPluginHandler::KioskSessionPluginHandler(
+    KioskSessionPluginHandlerDelegate* delegate)
+    : delegate_(delegate) {}
+
+KioskSessionPluginHandler::~KioskSessionPluginHandler() {}
+
+void KioskSessionPluginHandler::Observe(content::WebContents* contents) {
+  watchers_.push_back(new Observer(contents, this));
+}
+
+void KioskSessionPluginHandler::OnPluginCrashed(
+    const base::FilePath& plugin_path) {
+  delegate_->OnPluginCrashed(plugin_path);
+}
+
+void KioskSessionPluginHandler::OnPluginHung(
+    const std::set<int>& hung_plugins) {
+  delegate_->OnPluginHung(hung_plugins);
+}
+
+void KioskSessionPluginHandler::OnWebContentsDestroyed(Observer* observer) {
+  auto it = std::find(watchers_.begin(), watchers_.end(), observer);
+  if (it == watchers_.end())
+    return;
+
+  watchers_.weak_erase(it);
+
+  // Schedule the delete later after |observer|'s WebContentsDestroyed finishes.
+  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, observer);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler.h b/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler.h
new file mode 100644
index 0000000..b95dfac3
--- /dev/null
+++ b/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler.h
@@ -0,0 +1,51 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_SESSION_PLUGIN_HANDLER_H_
+#define CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_SESSION_PLUGIN_HANDLER_H_
+
+#include <set>
+
+#include "base/macros.h"
+#include "base/memory/scoped_vector.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace content {
+class WebContents;
+}
+
+namespace chromeos {
+
+class KioskSessionPluginHandlerDelegate;
+
+// A class to watch for plugin crash/hung in a kiosk session. Device will be
+// rebooted after the first crash/hung is detected.
+class KioskSessionPluginHandler {
+ public:
+  explicit KioskSessionPluginHandler(
+      KioskSessionPluginHandlerDelegate* delegate);
+  ~KioskSessionPluginHandler();
+
+  void Observe(content::WebContents* contents);
+
+ private:
+  // Observes WebContents for plugin crash/hung.
+  class Observer;
+
+  void OnPluginCrashed(const base::FilePath& plugin_path);
+  void OnPluginHung(const std::set<int>& hung_plugins);
+  void OnWebContentsDestroyed(Observer* observer);
+
+  KioskSessionPluginHandlerDelegate* const delegate_;
+  ScopedVector<Observer> watchers_;
+
+  DISALLOW_COPY_AND_ASSIGN(KioskSessionPluginHandler);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_SESSION_PLUGIN_HANDLER_H_
diff --git a/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler_delegate.h b/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler_delegate.h
new file mode 100644
index 0000000..fdc29783
--- /dev/null
+++ b/chrome/browser/chromeos/app_mode/kiosk_session_plugin_handler_delegate.h
@@ -0,0 +1,31 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_SESSION_PLUGIN_HANDLER_DELEGATE_H_
+#define CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_SESSION_PLUGIN_HANDLER_DELEGATE_H_
+
+#include <set>
+
+#include "base/files/file_path.h"
+
+namespace chromeos {
+
+class KioskSessionPluginHandlerDelegate {
+ public:
+  // Whether the plugin identified by the path should be handled.
+  virtual bool ShouldHandlePlugin(const base::FilePath& plugin_path) const = 0;
+
+  // Invoked after a plugin is crashed.
+  virtual void OnPluginCrashed(const base::FilePath& plugin_path) = 0;
+
+  // Invoked after plugins are hung.
+  virtual void OnPluginHung(const std::set<int>& hung_plugins) = 0;
+
+ protected:
+  virtual ~KioskSessionPluginHandlerDelegate() {}
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_APP_MODE_KIOSK_SESSION_PLUGIN_HANDLER_DELEGATE_H_
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
index 61e125b2..01e9c9f 100644
--- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
+++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
@@ -11,7 +11,6 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_diagnosis_runner.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
@@ -409,7 +408,7 @@
   OpenApplication(AppLaunchParams(profile_, extension,
                                   extensions::LAUNCH_CONTAINER_WINDOW,
                                   NEW_WINDOW, extensions::SOURCE_KIOSK));
-  InitAppSession(profile_, app_id_);
+  KioskAppManager::Get()->InitSession(profile_, app_id_);
 
   user_manager::UserManager::Get()->SessionStarted();
 
diff --git a/chrome/browser/chromeos/drive/download_handler.cc b/chrome/browser/chromeos/drive/download_handler.cc
index 06bc182..0e6897b 100644
--- a/chrome/browser/chromeos/drive/download_handler.cc
+++ b/chrome/browser/chromeos/drive/download_handler.cc
@@ -8,6 +8,7 @@
 #include "base/files/file_util.h"
 #include "base/strings/string_util.h"
 #include "base/supports_user_data.h"
+#include "base/thread_task_runner_handle.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
@@ -34,6 +35,11 @@
 const char* kGenericMimeTypes[] = {"text/html", "text/plain",
                                    "application/octet-stream"};
 
+// Longer is better. But at the same time, this value should be short enough as
+// drive::internal::kMinFreeSpaceInBytes is not used up by file download in this
+// interval.
+const base::TimeDelta kFreeDiskSpaceDelay = base::TimeDelta::FromSeconds(3);
+
 // User Data stored in DownloadItem for drive path.
 class DriveUserData : public base::SupportsUserData::Data {
  public:
@@ -125,12 +131,15 @@
   return mime_type;
 }
 
+void IgnoreFreeDiskSpaceIfNeededForCallback(bool /*result*/) {}
+
 }  // namespace
 
 DownloadHandler::DownloadHandler(FileSystemInterface* file_system)
     : file_system_(file_system),
-      weak_ptr_factory_(this) {
-}
+      has_pending_free_disk_space_(false),
+      free_disk_space_delay_(kFreeDiskSpaceDelay),
+      weak_ptr_factory_(this) {}
 
 DownloadHandler::~DownloadHandler() {
 }
@@ -237,8 +246,69 @@
                  callback));
 }
 
+void DownloadHandler::SetFreeDiskSpaceDelayForTesting(
+    const base::TimeDelta& delay) {
+  free_disk_space_delay_ = delay;
+}
+
+int64 DownloadHandler::CalculateRequestSpace(
+    const DownloadManager::DownloadVector& downloads) {
+  int64 request_space = 0;
+
+  for (const auto* download : downloads) {
+    if (download->IsDone())
+      continue;
+
+    const int64 total_bytes = download->GetTotalBytes();
+    // Skip unknown size download. Since drive cache tries to keep
+    // drive::internal::kMinFreeSpaceInBytes, we can continue download with
+    // using the space temporally.
+    if (total_bytes == 0)
+      continue;
+
+    request_space += total_bytes - download->GetReceivedBytes();
+  }
+
+  return request_space;
+}
+
+void DownloadHandler::FreeDiskSpaceIfNeeded() {
+  if (has_pending_free_disk_space_)
+    return;
+
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE, base::Bind(&DownloadHandler::FreeDiskSpaceIfNeededImmediately,
+                            weak_ptr_factory_.GetWeakPtr()),
+      free_disk_space_delay_);
+
+  has_pending_free_disk_space_ = true;
+}
+
+void DownloadHandler::FreeDiskSpaceIfNeededImmediately() {
+  DownloadManager::DownloadVector downloads;
+
+  // Get all downloads of current profile and its off-the-record profile.
+  // TODO(yawano): support multi profiles.
+  if (notifier_ && notifier_->GetManager()) {
+    notifier_->GetManager()->GetAllDownloads(&downloads);
+  }
+  if (notifier_incognito_ && notifier_incognito_->GetManager()) {
+    notifier_incognito_->GetManager()->GetAllDownloads(&downloads);
+  }
+
+  // Free disk space even if request size is 0 byte in order to make drive cache
+  // keep drive::internal::kMinFreeSpaceInBytes.
+  file_system_->FreeDiskSpaceIfNeededFor(
+      CalculateRequestSpace(downloads),
+      base::Bind(&IgnoreFreeDiskSpaceIfNeededForCallback));
+
+  has_pending_free_disk_space_ = false;
+}
+
 void DownloadHandler::OnDownloadCreated(DownloadManager* manager,
                                         DownloadItem* download) {
+  FreeDiskSpaceIfNeededImmediately();
+
   // Remove any persisted Drive DownloadItem. crbug.com/171384
   if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) {
     // Remove download later, since doing it here results in a crash.
@@ -265,6 +335,8 @@
     DownloadManager* manager, DownloadItem* download) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
+  FreeDiskSpaceIfNeeded();
+
   // Only accept downloads that have the Drive meta data associated with them.
   DriveUserData* data = GetDriveUserData(download);
   if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) ||
diff --git a/chrome/browser/chromeos/drive/download_handler.h b/chrome/browser/chromeos/drive/download_handler.h
index 9973224c..c0f36d1 100644
--- a/chrome/browser/chromeos/drive/download_handler.h
+++ b/chrome/browser/chromeos/drive/download_handler.h
@@ -73,6 +73,21 @@
       const content::DownloadItem* download,
       const content::CheckForFileExistenceCallback& callback);
 
+  // Calculates request space for |downloads|.
+  int64 CalculateRequestSpace(
+      const content::DownloadManager::DownloadVector& downloads);
+
+  // Checks available storage space and free disk space if necessary. Actual
+  // execution is delayed and rate limited.
+  void FreeDiskSpaceIfNeeded();
+
+  // Checks available storage space and free disk space if necessary. This is
+  // executed immediately.
+  void FreeDiskSpaceIfNeededImmediately();
+
+  // Sets free disk space delay for testing.
+  void SetFreeDiskSpaceDelayForTesting(const base::TimeDelta& delay);
+
  private:
   // AllDownloadItemNotifier::Observer overrides:
   void OnDownloadCreated(content::DownloadManager* manager,
@@ -104,6 +119,7 @@
   content::DownloadManager* GetDownloadManager(void* manager_id);
 
   FileSystemInterface* file_system_;  // Owned by DriveIntegrationService.
+
   // Observe the DownloadManager for new downloads.
   scoped_ptr<AllDownloadItemNotifier> notifier_;
   scoped_ptr<AllDownloadItemNotifier> notifier_incognito_;
@@ -111,6 +127,11 @@
   // Temporary download location directory.
   base::FilePath drive_tmp_download_path_;
 
+  // True if there is pending FreeDiskSpaceIfNeeded call.
+  bool has_pending_free_disk_space_;
+
+  base::TimeDelta free_disk_space_delay_;
+
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<DownloadHandler> weak_ptr_factory_;
diff --git a/chrome/browser/chromeos/drive/download_handler_unittest.cc b/chrome/browser/chromeos/drive/download_handler_unittest.cc
index 52bde91..20a75c94 100644
--- a/chrome/browser/chromeos/drive/download_handler_unittest.cc
+++ b/chrome/browser/chromeos/drive/download_handler_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/drive/download_handler.h"
 
 #include "base/files/scoped_temp_dir.h"
+#include "base/run_loop.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/drive/dummy_file_system.h"
@@ -42,16 +43,50 @@
     callback.Run(error_);
   }
 
+  void FreeDiskSpaceIfNeededFor(
+      int64 num_bytes,
+      const FreeDiskSpaceCallback& callback) override {
+    free_disk_space_if_needed_for_num_bytes_.push_back(num_bytes);
+    callback.Run(true);
+  }
+
+  std::vector<int64> free_disk_space_if_needed_for_num_bytes_;
+
  private:
   FileError error_;
 };
 
+class DownloadHandlerTestDownloadManager : public content::MockDownloadManager {
+ public:
+  void GetAllDownloads(
+      content::DownloadManager::DownloadVector* downloads) override {
+    for (auto* test_download : test_downloads_) {
+      downloads->push_back(test_download);
+    }
+  }
+
+  content::DownloadManager::DownloadVector test_downloads_;
+};
+
+class DownloadHandlerTestDownloadItem : public content::MockDownloadItem {
+ public:
+  bool IsDone() const override { return is_done_; }
+
+  int64 GetTotalBytes() const override { return total_bytes_; }
+
+  int64 GetReceivedBytes() const override { return received_bytes_; }
+
+  bool is_done_ = false;
+  int64 total_bytes_ = 0;
+  int64 received_bytes_ = 0;
+};
+
 }  // namespace
 
 class DownloadHandlerTest : public testing::Test {
  public:
   DownloadHandlerTest()
-      : download_manager_(new content::MockDownloadManager) {}
+      : download_manager_(new DownloadHandlerTestDownloadManager) {}
 
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
@@ -62,13 +97,16 @@
 
     download_handler_.reset(new DownloadHandler(&test_file_system_));
     download_handler_->Initialize(download_manager_.get(), temp_dir_.path());
+    download_handler_->SetFreeDiskSpaceDelayForTesting(
+        base::TimeDelta::FromMilliseconds(0));
   }
 
  protected:
   base::ScopedTempDir temp_dir_;
   content::TestBrowserThreadBundle thread_bundle_;
   TestingProfile profile_;
-  scoped_ptr<content::MockDownloadManager> download_manager_;
+  scoped_ptr<DownloadHandlerTestDownloadManager> download_manager_;
+  scoped_ptr<DownloadHandlerTestDownloadManager> incognito_download_manager_;
   DownloadHandlerTestFileSystem test_file_system_;
   scoped_ptr<DownloadHandler> download_handler_;
   content::MockDownloadItem download_item_;
@@ -196,4 +234,120 @@
   EXPECT_FALSE(file_exists);
 }
 
+TEST_F(DownloadHandlerTest, FreeDiskSpace) {
+  // Add a download item to download manager.
+  DownloadHandlerTestDownloadItem download_item_a;
+  download_item_a.is_done_ = false;
+  download_item_a.total_bytes_ = 100;
+  download_item_a.received_bytes_ = 10;
+  download_manager_->test_downloads_.push_back(&download_item_a);
+
+  // Free disk space for download_item_a.
+  download_handler_->FreeDiskSpaceIfNeededImmediately();
+  ASSERT_EQ(1u,
+            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
+  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
+            test_file_system_.free_disk_space_if_needed_for_num_bytes_[0]);
+
+  // Confirm that FreeDiskSpaceIfNeeded is rate limited by calling it twice.
+  download_handler_->FreeDiskSpaceIfNeeded();
+  download_handler_->FreeDiskSpaceIfNeeded();
+  ASSERT_EQ(1u,
+            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
+
+  download_item_a.received_bytes_ = 20;
+
+  base::RunLoop().RunUntilIdle();
+  ASSERT_EQ(2u,
+            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
+  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
+            test_file_system_.free_disk_space_if_needed_for_num_bytes_[1]);
+
+  // Observe incognito download manager and add another download item.
+  // FreeDiskSpace should be called with considering both download items.
+  incognito_download_manager_.reset(new DownloadHandlerTestDownloadManager);
+  download_handler_->ObserveIncognitoDownloadManager(
+      incognito_download_manager_.get());
+
+  DownloadHandlerTestDownloadItem download_item_b;
+  download_item_b.is_done_ = false;
+  download_item_b.total_bytes_ = 200;
+  download_item_b.received_bytes_ = 0;
+  incognito_download_manager_->test_downloads_.push_back(&download_item_b);
+
+  download_item_a.received_bytes_ = 30;
+
+  download_handler_->FreeDiskSpaceIfNeededImmediately();
+  ASSERT_EQ(3u,
+            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
+  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_ +
+                download_item_b.total_bytes_ - download_item_b.received_bytes_,
+            test_file_system_.free_disk_space_if_needed_for_num_bytes_[2]);
+
+  // Free disk space after making both items completed. In this case
+  // FreeDiskSpace should be called with 0 byte to keep
+  // drive::internal::kMinFreeSpaceInBytes.
+  download_item_a.is_done_ = true;
+  download_item_b.is_done_ = true;
+
+  download_handler_->FreeDiskSpaceIfNeeded();
+  base::RunLoop().RunUntilIdle();
+
+  ASSERT_EQ(4u,
+            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
+  ASSERT_EQ(0, test_file_system_.free_disk_space_if_needed_for_num_bytes_[3]);
+}
+
+TEST_F(DownloadHandlerTest, CalculateRequestSpace) {
+  DownloadHandlerTestDownloadItem download_item_a;
+  download_item_a.is_done_ = false;
+  download_item_a.total_bytes_ = 100;
+  download_item_a.received_bytes_ = 0;
+
+  DownloadHandlerTestDownloadItem download_item_b;
+  download_item_b.is_done_ = false;
+  download_item_b.total_bytes_ = 200;
+  download_item_b.received_bytes_ = 10;
+
+  content::DownloadManager::DownloadVector downloads;
+  downloads.push_back(&download_item_a);
+  downloads.push_back(&download_item_b);
+
+  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_ +
+                download_item_b.total_bytes_ - download_item_b.received_bytes_,
+            download_handler_->CalculateRequestSpace(downloads));
+
+  download_item_a.received_bytes_ = 10;
+
+  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_ +
+                download_item_b.total_bytes_ - download_item_b.received_bytes_,
+            download_handler_->CalculateRequestSpace(downloads));
+
+  download_item_b.is_done_ = true;
+
+  // Since download_item_b is completed, it shouldn't be counted.
+  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
+            download_handler_->CalculateRequestSpace(downloads));
+
+  // Add unknown size download item.
+  DownloadHandlerTestDownloadItem download_item_c;
+  download_item_c.is_done_ = false;
+  download_item_c.total_bytes_ = 0;
+  downloads.push_back(&download_item_c);
+
+  // Unknown size download should be counted as 0 byte.
+  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
+            download_handler_->CalculateRequestSpace(downloads));
+
+  // Add another unknown size download item.
+  DownloadHandlerTestDownloadItem download_item_d;
+  download_item_d.is_done_ = false;
+  download_item_d.total_bytes_ = 0;
+  downloads.push_back(&download_item_d);
+
+  // Unknown size downloads should be counted as 0 byte.
+  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
+            download_handler_->CalculateRequestSpace(downloads));
+}
+
 }  // namespace drive
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc
index a047afd..e417e360 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -22,10 +22,10 @@
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/ime/candidate_window.h"
 #include "ui/base/ime/chromeos/component_extension_ime_manager.h"
-#include "ui/base/ime/chromeos/composition_text_chromeos.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
 #include "ui/base/ime/chromeos/ime_keymap.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
+#include "ui/base/ime/composition_text.h"
 #include "ui/base/ime/ime_bridge.h"
 #include "ui/base/ime/text_input_flags.h"
 #include "ui/chromeos/ime/input_method_menu_item.h"
@@ -47,14 +47,14 @@
 const char kCandidateNotFound[] = "Candidate not found";
 
 // Notifies InputContextHandler that the composition is changed.
-void UpdateComposition(const CompositionText& composition_text,
+void UpdateComposition(const ui::CompositionText& composition_text,
                        uint32 cursor_pos,
                        bool is_visible) {
   ui::IMEInputContextHandlerInterface* input_context =
       ui::IMEBridge::Get()->GetInputContextHandler();
   if (input_context)
-    input_context->UpdateCompositionText(
-        composition_text, cursor_pos, is_visible);
+    input_context->UpdateCompositionText(composition_text, cursor_pos,
+                                         is_visible);
 }
 
 // Returns the length of characters of a UTF-8 string with unknown string
@@ -82,9 +82,8 @@
     return code.substr(5);
   if (code == "Escape")
     return "Esc";
-  if (code == "Backspace" || code == "Tab" ||
-      code == "Enter" || code == "CapsLock" ||
-      code == "Power")
+  if (code == "Backspace" || code == "Tab" || code == "Enter" ||
+      code == "CapsLock" || code == "Power")
     return code;
   // Cases for media keys.
   switch (event.key_code()) {
@@ -124,8 +123,7 @@
   uint16 ch = 0;
   // Ctrl+? cases, gets key value for Ctrl is not down.
   if (event.flags() & ui::EF_CONTROL_DOWN) {
-    ui::KeyEvent event_no_ctrl(event.type(),
-                               event.key_code(),
+    ui::KeyEvent event_no_ctrl(event.type(), event.key_code(),
                                event.flags() ^ ui::EF_CONTROL_DOWN);
     ch = event_no_ctrl.GetCharacter();
   } else {
@@ -160,21 +158,18 @@
     : current_input_type_(ui::TEXT_INPUT_TYPE_NONE),
       context_id_(0),
       next_context_id_(1),
-      composition_text_(new CompositionText()),
+      composition_text_(new ui::CompositionText()),
       composition_cursor_(0),
       candidate_window_(new ui::CandidateWindow()),
       window_visible_(false),
       sent_key_event_(NULL),
-      profile_(NULL) {
-}
+      profile_(NULL) {}
 
-InputMethodEngine::~InputMethodEngine() {
-}
+InputMethodEngine::~InputMethodEngine() {}
 
-void InputMethodEngine::Initialize(
-    scoped_ptr<InputMethodEngineInterface::Observer> observer,
-    const char* extension_id,
-    Profile* profile) {
+void InputMethodEngine::Initialize(scoped_ptr<ui::IMEEngineObserver> observer,
+                                   const char* extension_id,
+                                   Profile* profile) {
   DCHECK(observer) << "Observer must not be null.";
 
   // TODO(komatsu): It is probably better to set observer out of Initialize.
@@ -205,34 +200,35 @@
   }
 
   composition_cursor_ = cursor;
-  composition_text_.reset(new CompositionText());
-  composition_text_->set_text(base::UTF8ToUTF16(text));
+  composition_text_.reset(new ui::CompositionText());
+  composition_text_->text = base::UTF8ToUTF16(text);
 
-  composition_text_->set_selection_start(selection_start);
-  composition_text_->set_selection_end(selection_end);
+  composition_text_->selection.set_start(selection_start);
+  composition_text_->selection.set_end(selection_end);
 
   // TODO: Add support for displaying selected text in the composition string.
   for (std::vector<SegmentInfo>::const_iterator segment = segments.begin();
        segment != segments.end(); ++segment) {
-    CompositionText::UnderlineAttribute underline;
+    ui::CompositionUnderline underline;
 
     switch (segment->style) {
       case SEGMENT_STYLE_UNDERLINE:
-        underline.type = CompositionText::COMPOSITION_TEXT_UNDERLINE_SINGLE;
+        underline.color = SK_ColorBLACK;
         break;
       case SEGMENT_STYLE_DOUBLE_UNDERLINE:
-        underline.type = CompositionText::COMPOSITION_TEXT_UNDERLINE_DOUBLE;
+        underline.color = SK_ColorBLACK;
+        underline.thick = true;
         break;
       case SEGMENT_STYLE_NO_UNDERLINE:
-        underline.type = CompositionText::COMPOSITION_TEXT_UNDERLINE_NONE;
+        underline.color = SK_ColorTRANSPARENT;
         break;
       default:
         continue;
     }
 
-    underline.start_index = segment->start;
-    underline.end_index = segment->end;
-    composition_text_->mutable_underline_attributes()->push_back(underline);
+    underline.start_offset = segment->start;
+    underline.end_offset = segment->end;
+    composition_text_->underlines.push_back(underline);
   }
 
   // TODO(nona): Makes focus out mode configuable, if necessary.
@@ -240,8 +236,7 @@
   return true;
 }
 
-bool InputMethodEngine::ClearComposition(int context_id,
-                                         std::string* error)  {
+bool InputMethodEngine::ClearComposition(int context_id, std::string* error) {
   if (!IsActive()) {
     *error = kErrorNotActive;
     return false;
@@ -252,12 +247,13 @@
   }
 
   composition_cursor_ = 0;
-  composition_text_.reset(new CompositionText());
+  composition_text_.reset(new ui::CompositionText());
   UpdateComposition(*composition_text_, composition_cursor_, false);
   return true;
 }
 
-bool InputMethodEngine::CommitText(int context_id, const char* text,
+bool InputMethodEngine::CommitText(int context_id,
+                                   const char* text,
                                    std::string* error) {
   if (!IsActive()) {
     // TODO: Commit the text anyways.
@@ -272,11 +268,11 @@
   ui::IMEBridge::Get()->GetInputContextHandler()->CommitText(text);
 
   // Records histograms for committed characters.
-  if (!composition_text_->text().empty()) {
+  if (!composition_text_->text.empty()) {
     size_t len = GetUtf8StringLength(text);
     UMA_HISTOGRAM_CUSTOM_COUNTS("InputMethod.CommitLength",
                                 len, 1, 25, 25);
-    composition_text_.reset(new CompositionText());
+    composition_text_.reset(new ui::CompositionText());
   }
   return true;
 }
@@ -305,9 +301,9 @@
       key_code = ui::DomKeycodeToKeyboardCode(event.code);
 
     int flags = ui::EF_NONE;
-    flags |= event.alt_key   ? ui::EF_ALT_DOWN       : ui::EF_NONE;
-    flags |= event.ctrl_key  ? ui::EF_CONTROL_DOWN   : ui::EF_NONE;
-    flags |= event.shift_key ? ui::EF_SHIFT_DOWN     : ui::EF_NONE;
+    flags |= event.alt_key ? ui::EF_ALT_DOWN : ui::EF_NONE;
+    flags |= event.ctrl_key ? ui::EF_CONTROL_DOWN : ui::EF_NONE;
+    flags |= event.shift_key ? ui::EF_SHIFT_DOWN : ui::EF_NONE;
     flags |= event.caps_lock ? ui::EF_CAPS_LOCK_DOWN : ui::EF_NONE;
 
     ui::KeyEvent ui_event(
@@ -332,7 +328,7 @@
 
 void InputMethodEngine::SetCandidateWindowProperty(
     const CandidateWindowProperty& property) {
-  // Type conversion from InputMethodEngineInterface::CandidateWindowProperty to
+  // Type conversion from IMEEngineHandlerInterface::CandidateWindowProperty to
   // CandidateWindow::CandidateWindowProperty defined in chromeos/ime/.
   ui::CandidateWindow::CandidateWindowProperty dest_property;
   dest_property.page_size = property.page_size;
@@ -412,7 +408,8 @@
   return true;
 }
 
-bool InputMethodEngine::SetCursorPosition(int context_id, int candidate_id,
+bool InputMethodEngine::SetCursorPosition(int context_id,
+                                          int candidate_id,
                                           std::string* error) {
   if (!IsActive()) {
     *error = kErrorNotActive;
@@ -455,9 +452,8 @@
     menu_item_list.push_back(property);
   }
 
-  ui::ime::InputMethodMenuManager::GetInstance()->
-      SetCurrentInputMethodMenuItemList(
-          menu_item_list);
+  ui::ime::InputMethodMenuManager::GetInstance()
+      ->SetCurrentInputMethodMenuItemList(menu_item_list);
   return true;
 }
 
@@ -490,7 +486,7 @@
 
 void InputMethodEngine::HideInputView() {
   keyboard::KeyboardController* keyboard_controller =
-    keyboard::KeyboardController::GetInstance();
+      keyboard::KeyboardController::GetInstance();
   if (keyboard_controller) {
     keyboard_controller->HideKeyboard(
         keyboard::KeyboardController::HIDE_REASON_MANUAL);
@@ -527,40 +523,9 @@
   context_id_ = next_context_id_;
   ++next_context_id_;
 
-  InputMethodEngineInterface::InputContext context;
-  context.id = context_id_;
-  switch (current_input_type_) {
-    case ui::TEXT_INPUT_TYPE_SEARCH:
-      context.type = "search";
-      break;
-    case ui::TEXT_INPUT_TYPE_TELEPHONE:
-      context.type = "tel";
-      break;
-    case ui::TEXT_INPUT_TYPE_URL:
-      context.type = "url";
-      break;
-    case ui::TEXT_INPUT_TYPE_EMAIL:
-      context.type = "email";
-      break;
-    case ui::TEXT_INPUT_TYPE_NUMBER:
-      context.type = "number";
-      break;
-    case ui::TEXT_INPUT_TYPE_PASSWORD:
-      context.type = "password";
-      break;
-    default:
-      context.type = "text";
-      break;
-  }
-
-  context.auto_correct =
-      !(input_context.flags & ui::TEXT_INPUT_FLAG_AUTOCORRECT_OFF);
-  context.auto_complete =
-      !(input_context.flags & ui::TEXT_INPUT_FLAG_AUTOCOMPLETE_OFF);
-  context.spell_check =
-      !(input_context.flags & ui::TEXT_INPUT_FLAG_SPELLCHECK_OFF);
-
-  observer_->OnFocus(context);
+  observer_->OnFocus(ui::IMEEngineHandlerInterface::InputContext(
+      context_id_, input_context.type, input_context.mode,
+      input_context.flags));
 }
 
 void InputMethodEngine::FocusOut() {
@@ -594,8 +559,8 @@
     return;
   active_component_id_.clear();
   ui::IMEBridge::Get()->GetInputContextHandler()->CommitText(
-      base::UTF16ToUTF8(composition_text_->text()));
-  composition_text_.reset(new CompositionText());
+      base::UTF16ToUTF8(composition_text_->text));
+  composition_text_.reset(new ui::CompositionText());
   observer_->OnDeactivated(active_component_id_);
 }
 
@@ -608,7 +573,7 @@
 void InputMethodEngine::Reset() {
   if (!CheckProfile())
     return;
-  composition_text_.reset(new CompositionText());
+  composition_text_.reset(new ui::CompositionText());
   observer_->OnReset(active_component_id_);
 }
 
@@ -616,15 +581,11 @@
   return observer_->IsInterestedInKeyEvent();
 }
 
-void InputMethodEngine::ProcessKeyEvent(
-    const ui::KeyEvent& key_event,
-    const KeyEventDoneCallback& callback) {
+void InputMethodEngine::ProcessKeyEvent(const ui::KeyEvent& key_event,
+                                        KeyEventDoneCallback& callback) {
   if (!CheckProfile())
     return;
 
-  KeyEventDoneCallback* handler = new KeyEventDoneCallback();
-  *handler = callback;
-
   KeyboardEvent ext_event;
   GetExtensionKeyboardEventFromKeyEvent(key_event, &ext_event);
 
@@ -635,10 +596,7 @@
   if (&key_event == sent_key_event_)
     ext_event.extension_id = extension_id_;
 
-  observer_->OnKeyEvent(
-      active_component_id_,
-      ext_event,
-      reinterpret_cast<input_method::KeyEventHandle*>(handler));
+  observer_->OnKeyEvent(active_component_id_, ext_event, callback);
 }
 
 void InputMethodEngine::CandidateClicked(uint32 index) {
@@ -649,8 +607,8 @@
   }
 
   // Only left button click is supported at this moment.
-  observer_->OnCandidateClicked(
-      active_component_id_, candidate_ids_.at(index), MOUSE_BUTTON_LEFT);
+  observer_->OnCandidateClicked(active_component_id_, candidate_ids_.at(index),
+                                ui::IMEEngineObserver::MOUSE_BUTTON_LEFT);
 }
 
 void InputMethodEngine::SetSurroundingText(const std::string& text,
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h
index 497bc8e..72e9461 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine.h
@@ -9,14 +9,18 @@
 #include <string>
 #include <vector>
 #include "base/time/time.h"
-#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
 #include "ui/base/ime/chromeos/input_method_descriptor.h"
+#include "ui/base/ime/ime_engine_handler_interface.h"
+#include "ui/base/ime/ime_engine_observer.h"
 #include "url/gurl.h"
 
 class Profile;
 
 namespace ui {
 class CandidateWindow;
+struct CompositionText;
+class IMEEngineHandlerInterface;
+class IMEEngineObserver;
 class KeyEvent;
 
 namespace ime {
@@ -26,23 +30,17 @@
 
 namespace chromeos {
 
-class CompositionText;
-
-namespace input_method {
-struct KeyEventHandle;
-}  // namespace input_method
-
-class InputMethodEngine : public InputMethodEngineInterface {
+class InputMethodEngine : public ui::IMEEngineHandlerInterface {
  public:
   InputMethodEngine();
 
   ~InputMethodEngine() override;
 
-  void Initialize(scoped_ptr<InputMethodEngineInterface::Observer> observer,
+  void Initialize(scoped_ptr<ui::IMEEngineObserver> observer,
                   const char* extension_id,
                   Profile* profile);
 
-  // InputMethodEngineInterface overrides.
+  // IMEEngineHandlerInterface overrides.
   const std::string& GetActiveComponentId() const override;
   bool SetComposition(int context_id,
                       const char* text,
@@ -84,7 +82,7 @@
   void PropertyActivate(const std::string& property_name) override;
   void Reset() override;
   void ProcessKeyEvent(const ui::KeyEvent& key_event,
-                       const KeyEventDoneCallback& callback) override;
+                       KeyEventDoneCallback& callback) override;
   void CandidateClicked(uint32 index) override;
   void SetSurroundingText(const std::string& text,
                           uint32 cursor_pos,
@@ -121,10 +119,10 @@
   std::string extension_id_;
 
   // The observer object recieving events for this IME.
-  scoped_ptr<InputMethodEngineInterface::Observer> observer_;
+  scoped_ptr<ui::IMEEngineObserver> observer_;
 
   // The current preedit text, and it's cursor position.
-  scoped_ptr<CompositionText> composition_text_;
+  scoped_ptr<ui::CompositionText> composition_text_;
   int composition_cursor_;
 
   // The current candidate window.
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
index 2f911c0..fc0d68c 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
@@ -12,12 +12,12 @@
 #include "extensions/common/manifest_handlers/background_info.h"
 #include "extensions/test/extension_test_message_listener.h"
 #include "ui/base/ime/chromeos/component_extension_ime_manager.h"
-#include "ui/base/ime/chromeos/composition_text_chromeos.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
 #include "ui/base/ime/chromeos/input_method_descriptor.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h"
 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
+#include "ui/base/ime/composition_text.h"
 #include "ui/base/ime/ime_bridge.h"
 #include "ui/base/ime/ime_engine_handler_interface.h"
 #include "ui/base/ime/text_input_flags.h"
@@ -185,9 +185,9 @@
   KeyEventDoneCallback callback(false);  // EchoBackIME doesn't consume keys.
   ExtensionTestMessageListener keyevent_listener("onKeyEvent", false);
   ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
-  engine_handler->ProcessKeyEvent(key_event,
-                                  base::Bind(&KeyEventDoneCallback::Run,
-                                             base::Unretained(&callback)));
+  ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+      base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+  engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
   ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
   ASSERT_TRUE(keyevent_listener.was_satisfied());
   callback.WaitUntilCalled();
@@ -269,9 +269,9 @@
 
     ui::KeyEvent key_event(
         ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::KEY_A, ui::EF_NONE);
-    engine_handler->ProcessKeyEvent(key_event,
-                                    base::Bind(&KeyEventDoneCallback::Run,
-                                               base::Unretained(&callback)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+        base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+    engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
     ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
     EXPECT_TRUE(keyevent_listener.was_satisfied());
     callback.WaitUntilCalled();
@@ -287,9 +287,9 @@
                            ui::VKEY_A,
                            ui::DomCode::KEY_A,
                            ui::EF_CONTROL_DOWN);
-    engine_handler->ProcessKeyEvent(key_event,
-                                    base::Bind(&KeyEventDoneCallback::Run,
-                                               base::Unretained(&callback)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+        base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+    engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
     ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
     EXPECT_TRUE(keyevent_listener.was_satisfied());
     callback.WaitUntilCalled();
@@ -305,9 +305,9 @@
                            ui::VKEY_A,
                            ui::DomCode::KEY_A,
                            ui::EF_ALT_DOWN);
-    engine_handler->ProcessKeyEvent(key_event,
-                                    base::Bind(&KeyEventDoneCallback::Run,
-                                               base::Unretained(&callback)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+        base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+    engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
     ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
     EXPECT_TRUE(keyevent_listener.was_satisfied());
     callback.WaitUntilCalled();
@@ -323,9 +323,9 @@
                            ui::VKEY_A,
                            ui::DomCode::KEY_A,
                            ui::EF_SHIFT_DOWN);
-    engine_handler->ProcessKeyEvent(key_event,
-                                    base::Bind(&KeyEventDoneCallback::Run,
-                                               base::Unretained(&callback)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+        base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+    engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
     ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
     EXPECT_TRUE(keyevent_listener.was_satisfied());
     callback.WaitUntilCalled();
@@ -341,9 +341,9 @@
                            ui::VKEY_A,
                            ui::DomCode::KEY_A,
                            ui::EF_CAPS_LOCK_DOWN);
-    engine_handler->ProcessKeyEvent(key_event,
-                                    base::Bind(&KeyEventDoneCallback::Run,
-                                               base::Unretained(&callback)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+        base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+    engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
     ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
     EXPECT_TRUE(keyevent_listener.was_satisfied());
     callback.WaitUntilCalled();
@@ -359,9 +359,9 @@
                            ui::VKEY_A,
                            ui::DomCode::KEY_A,
                            ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN);
-    engine_handler->ProcessKeyEvent(key_event,
-                                    base::Bind(&KeyEventDoneCallback::Run,
-                                               base::Unretained(&callback)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+        base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+    engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
     ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
     EXPECT_TRUE(keyevent_listener.was_satisfied());
     callback.WaitUntilCalled();
@@ -377,9 +377,9 @@
                            ui::VKEY_A,
                            ui::DomCode::KEY_A,
                            ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN);
-    engine_handler->ProcessKeyEvent(key_event,
-                                    base::Bind(&KeyEventDoneCallback::Run,
-                                               base::Unretained(&callback)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+        base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+    engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
     ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
     EXPECT_TRUE(keyevent_listener.was_satisfied());
     callback.WaitUntilCalled();
@@ -425,9 +425,9 @@
         kMediaKeyCases[i].keycode,
         ui::KeycodeConverter::CodeStringToDomCode(kMediaKeyCases[i].code),
         ui::EF_NONE);
-    engine_handler->ProcessKeyEvent(key_event,
-                                    base::Bind(&KeyEventDoneCallback::Run,
-                                               base::Unretained(&callback)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback =
+        base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback));
+    engine_handler->ProcessKeyEvent(key_event, keyevent_callback);
     ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
     EXPECT_TRUE(keyevent_listener.was_satisfied());
     callback.WaitUntilCalled();
@@ -556,22 +556,23 @@
               mock_input_context->last_update_composition_arg().cursor_pos);
     EXPECT_TRUE(mock_input_context->last_update_composition_arg().is_visible);
 
-    const CompositionText& composition_text =
+    const ui::CompositionText& composition_text =
         mock_input_context->last_update_composition_arg().composition_text;
-    EXPECT_EQ(base::UTF8ToUTF16("COMPOSITION_TEXT"), composition_text.text());
-    const std::vector<CompositionText::UnderlineAttribute>& underlines =
-        composition_text.underline_attributes();
+    EXPECT_EQ(base::UTF8ToUTF16("COMPOSITION_TEXT"), composition_text.text);
+    const ui::CompositionUnderlines underlines = composition_text.underlines;
 
     ASSERT_EQ(2U, underlines.size());
-    EXPECT_EQ(CompositionText::COMPOSITION_TEXT_UNDERLINE_SINGLE,
-              underlines[0].type);
-    EXPECT_EQ(0U, underlines[0].start_index);
-    EXPECT_EQ(5U, underlines[0].end_index);
+    // single underline
+    EXPECT_EQ(SK_ColorBLACK, underlines[0].color);
+    EXPECT_FALSE(underlines[0].thick);
+    EXPECT_EQ(0U, underlines[0].start_offset);
+    EXPECT_EQ(5U, underlines[0].end_offset);
 
-    EXPECT_EQ(CompositionText::COMPOSITION_TEXT_UNDERLINE_DOUBLE,
-              underlines[1].type);
-    EXPECT_EQ(6U, underlines[1].start_index);
-    EXPECT_EQ(10U, underlines[1].end_index);
+    // double underline
+    EXPECT_EQ(SK_ColorBLACK, underlines[1].color);
+    EXPECT_TRUE(underlines[1].thick);
+    EXPECT_EQ(6U, underlines[1].start_offset);
+    EXPECT_EQ(10U, underlines[1].end_offset);
   }
   {
     SCOPED_TRACE("clearComposition test");
@@ -588,9 +589,9 @@
     EXPECT_EQ(1, mock_input_context->update_preedit_text_call_count());
     EXPECT_FALSE(
         mock_input_context->last_update_composition_arg().is_visible);
-    const CompositionText& composition_text =
+    const ui::CompositionText& composition_text =
         mock_input_context->last_update_composition_arg().composition_text;
-    EXPECT_TRUE(composition_text.text().empty());
+    EXPECT_TRUE(composition_text.text.empty());
   }
   {
     SCOPED_TRACE("setCandidateWindowProperties:visibility test");
@@ -1013,17 +1014,17 @@
     EXPECT_EQ(2U, mock_input_context->last_update_composition_arg().cursor_pos);
     EXPECT_TRUE(mock_input_context->last_update_composition_arg().is_visible);
 
-    const CompositionText& composition_text =
+    const ui::CompositionText& composition_text =
         mock_input_context->last_update_composition_arg().composition_text;
-    EXPECT_EQ(base::UTF8ToUTF16("us"), composition_text.text());
-    const std::vector<CompositionText::UnderlineAttribute>& underlines =
-        composition_text.underline_attributes();
+    EXPECT_EQ(base::UTF8ToUTF16("us"), composition_text.text);
+    const ui::CompositionUnderlines underlines = composition_text.underlines;
 
     ASSERT_EQ(1U, underlines.size());
-    EXPECT_EQ(CompositionText::COMPOSITION_TEXT_UNDERLINE_SINGLE,
-              underlines[0].type);
-    EXPECT_EQ(0U, underlines[0].start_index);
-    EXPECT_EQ(1U, underlines[0].end_index);
+    // single underline
+    EXPECT_EQ(SK_ColorBLACK, underlines[0].color);
+    EXPECT_FALSE(underlines[0].thick);
+    EXPECT_EQ(0U, underlines[0].start_offset);
+    EXPECT_EQ(1U, underlines[0].end_offset);
     EXPECT_TRUE(mock_input_context->last_commit_text().empty());
 
     InputMethodManager::Get()->GetActiveIMEState()->ChangeInputMethod(
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_interface.cc b/chrome/browser/chromeos/input_method/input_method_engine_interface.cc
deleted file mode 100644
index 102ef15c..0000000
--- a/chrome/browser/chromeos/input_method/input_method_engine_interface.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
-
-namespace chromeos {
-
-InputMethodEngineInterface::KeyboardEvent::KeyboardEvent()
-    : alt_key(false),
-      ctrl_key(false),
-      shift_key(false),
-      caps_lock(false) {
-}
-
-InputMethodEngineInterface::KeyboardEvent::~KeyboardEvent() {
-}
-
-InputMethodEngineInterface::MenuItem::MenuItem() {
-}
-
-InputMethodEngineInterface::MenuItem::~MenuItem() {
-}
-
-InputMethodEngineInterface::Candidate::Candidate() {
-}
-
-InputMethodEngineInterface::Candidate::~Candidate() {
-}
-
-namespace {
-// The default entry number of a page in CandidateWindowProperty.
-const int kDefaultPageSize = 9;
-}  // namespace
-
-// When the default values are changed, please modify
-// CandidateWindow::CandidateWindowProperty defined in chromeos/ime/ too.
-InputMethodEngineInterface::CandidateWindowProperty::CandidateWindowProperty()
-    : page_size(kDefaultPageSize),
-      is_cursor_visible(true),
-      is_vertical(false),
-      show_window_at_composition(false) {
-}
-
-InputMethodEngineInterface::CandidateWindowProperty::~CandidateWindowProperty()
-{
-}
-
-InputMethodEngineInterface::Observer::~Observer() {
-}
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_interface.h b/chrome/browser/chromeos/input_method/input_method_engine_interface.h
deleted file mode 100644
index 5120831..0000000
--- a/chrome/browser/chromeos/input_method/input_method_engine_interface.h
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_ENGINE_INTERFACE_H_
-#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_ENGINE_INTERFACE_H_
-
-#include <string>
-#include <vector>
-
-#include "ui/base/ime/ime_engine_handler_interface.h"
-
-class GURL;
-
-namespace chromeos {
-
-namespace input_method {
-class InputMethodDescriptor;
-struct KeyEventHandle;
-}  // namespace input_method
-
-// InputMethodEngine is used to translate from the Chrome IME API to the native
-// API.
-class InputMethodEngineInterface : public ui::IMEEngineHandlerInterface {
- public:
-  struct KeyboardEvent {
-    KeyboardEvent();
-    virtual ~KeyboardEvent();
-
-    std::string type;
-    std::string key;
-    std::string code;
-    int key_code; // only used by on-screen keyboards.
-    std::string extension_id;
-    bool alt_key;
-    bool ctrl_key;
-    bool shift_key;
-    bool caps_lock;
-  };
-
-  enum {
-    MENU_ITEM_MODIFIED_LABEL        = 0x0001,
-    MENU_ITEM_MODIFIED_STYLE        = 0x0002,
-    MENU_ITEM_MODIFIED_VISIBLE      = 0x0004,
-    MENU_ITEM_MODIFIED_ENABLED      = 0x0008,
-    MENU_ITEM_MODIFIED_CHECKED      = 0x0010,
-    MENU_ITEM_MODIFIED_ICON         = 0x0020,
-  };
-
-  enum MenuItemStyle {
-    MENU_ITEM_STYLE_NONE,
-    MENU_ITEM_STYLE_CHECK,
-    MENU_ITEM_STYLE_RADIO,
-    MENU_ITEM_STYLE_SEPARATOR,
-  };
-
-  enum MouseButtonEvent {
-    MOUSE_BUTTON_LEFT,
-    MOUSE_BUTTON_RIGHT,
-    MOUSE_BUTTON_MIDDLE,
-  };
-
-  enum SegmentStyle {
-    SEGMENT_STYLE_UNDERLINE,
-    SEGMENT_STYLE_DOUBLE_UNDERLINE,
-    SEGMENT_STYLE_NO_UNDERLINE,
-  };
-
-  enum CandidateWindowPosition {
-    WINDOW_POS_CURSOR,
-    WINDOW_POS_COMPOSITTION,
-  };
-
-  struct MenuItem {
-    MenuItem();
-    virtual ~MenuItem();
-
-    std::string id;
-    std::string label;
-    MenuItemStyle style;
-    bool visible;
-    bool enabled;
-    bool checked;
-
-    unsigned int modified;
-    std::vector<MenuItem> children;
-  };
-
-  struct InputContext {
-    int id;
-    std::string type;
-    bool auto_correct;
-    bool auto_complete;
-    bool spell_check;
-  };
-
-  struct UsageEntry {
-    std::string title;
-    std::string body;
-  };
-
-  struct Candidate {
-    Candidate();
-    virtual ~Candidate();
-
-    std::string value;
-    int id;
-    std::string label;
-    std::string annotation;
-    UsageEntry usage;
-    std::vector<Candidate> candidates;
-  };
-
-  struct CandidateWindowProperty {
-    CandidateWindowProperty();
-    virtual ~CandidateWindowProperty();
-    int page_size;
-    bool is_cursor_visible;
-    bool is_vertical;
-    bool show_window_at_composition;
-
-    // Auxiliary text is typically displayed in the footer of the candidate
-    // window.
-    std::string auxiliary_text;
-    bool is_auxiliary_text_visible;
-  };
-
-  struct SegmentInfo {
-    int start;
-    int end;
-    SegmentStyle style;
-  };
-
-  class Observer {
-   public:
-    virtual ~Observer();
-
-    // Called when the IME becomes the active IME.
-    virtual void OnActivate(const std::string& engine_id) = 0;
-
-    // Called when the IME is no longer active.
-    virtual void OnDeactivated(const std::string& engine_id) = 0;
-
-    // Called when a text field gains focus, and will be sending key events.
-    virtual void OnFocus(const InputContext& context) = 0;
-
-    // Called when a text field loses focus, and will no longer generate events.
-    virtual void OnBlur(int context_id) = 0;
-
-    // Called when an InputContext's properties change while it is focused.
-    virtual void OnInputContextUpdate(const InputContext& context) = 0;
-
-    // Returns whether the observer is interested in key events.
-    virtual bool IsInterestedInKeyEvent() const = 0;
-
-    // Called when the user pressed a key with a text field focused.
-    virtual void OnKeyEvent(const std::string& engine_id,
-                            const KeyboardEvent& event,
-                            input_method::KeyEventHandle* key_data) = 0;
-
-    // Called when the user clicks on an item in the candidate list.
-    virtual void OnCandidateClicked(const std::string& engine_id,
-                                    int candidate_id,
-                                    MouseButtonEvent button) = 0;
-
-    // Called when a menu item for this IME is interacted with.
-    virtual void OnMenuItemActivated(const std::string& engine_id,
-                                     const std::string& menu_id) = 0;
-
-    // Called when a surrounding text is changed.
-    virtual void OnSurroundingTextChanged(const std::string& engine_id,
-                                          const std::string& text,
-                                          int cursor_pos,
-                                          int anchor_pos,
-                                          int offset_pos) = 0;
-
-    // Called when composition bounds are changed.
-    virtual void OnCompositionBoundsChanged(
-        const std::vector<gfx::Rect>& bounds) = 0;
-
-    // Called when Chrome terminates on-going text input session.
-    virtual void OnReset(const std::string& engine_id) = 0;
-  };
-
-  ~InputMethodEngineInterface() override {}
-
-  // Set the current composition and associated properties.
-  virtual bool SetComposition(int context_id,
-                              const char* text,
-                              int selection_start,
-                              int selection_end,
-                              int cursor,
-                              const std::vector<SegmentInfo>& segments,
-                              std::string* error) = 0;
-
-  // Clear the current composition.
-  virtual bool ClearComposition(int context_id, std::string* error) = 0;
-
-  // Commit the specified text to the specified context.  Fails if the context
-  // is not focused.
-  virtual bool CommitText(int context_id, const char* text,
-                          std::string* error) = 0;
-
-  // Send the sequence of key events.
-  virtual bool SendKeyEvents(int context_id,
-                             const std::vector<KeyboardEvent>& events) = 0;
-
-  // This function returns the current property of the candidate window.
-  // The caller can use the returned value as the default property and
-  // modify some of specified items.
-  virtual const CandidateWindowProperty&
-    GetCandidateWindowProperty() const = 0;
-
-  // Change the property of the candidate window and repaint the candidate
-  // window widget.
-  virtual void SetCandidateWindowProperty(
-      const CandidateWindowProperty& property) = 0;
-
-  // Show or hide the candidate window.
-  virtual bool SetCandidateWindowVisible(bool visible, std::string* error) = 0;
-
-  // Set the list of entries displayed in the candidate window.
-  virtual bool SetCandidates(int context_id,
-                             const std::vector<Candidate>& candidates,
-                             std::string* error) = 0;
-
-  // Set the position of the cursor in the candidate window.
-  virtual bool SetCursorPosition(int context_id, int candidate_id,
-                                 std::string* error) = 0;
-
-  // Set the list of items that appears in the language menu when this IME is
-  // active.
-  virtual bool SetMenuItems(const std::vector<MenuItem>& items) = 0;
-
-  // Update the state of the menu items.
-  virtual bool UpdateMenuItems(const std::vector<MenuItem>& items) = 0;
-
-  // Returns true if this IME is active, false if not.
-  virtual bool IsActive() const = 0;
-
-  // Returns the current active input_component id.
-  virtual const std::string& GetActiveComponentId() const = 0;
-
-  // Deletes |number_of_chars| unicode characters as the basis of |offset| from
-  // the surrounding text. The |offset| is relative position based on current
-  // caret.
-  // NOTE: Currently we are falling back to backspace forwarding workaround,
-  // because delete_surrounding_text is not supported in Chrome. So this
-  // function is restricted for only preceding text.
-  // TODO(nona): Support full spec delete surrounding text.
-  virtual bool DeleteSurroundingText(int context_id,
-                                     int offset,
-                                     size_t number_of_chars,
-                                     std::string* error) = 0;
-
-  // Hides the input view window (from API call).
-  virtual void HideInputView() = 0;
-};
-
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_ENGINE_INTERFACE_H_
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
index 75b919c..51127ed 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/test/histogram_tester.h"
 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
-#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -17,6 +16,8 @@
 #include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h"
 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
 #include "ui/base/ime/ime_bridge.h"
+#include "ui/base/ime/ime_engine_handler_interface.h"
+#include "ui/base/ime/ime_engine_observer.h"
 #include "ui/base/ime/text_input_flags.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -65,7 +66,7 @@
   InitializeForTesting(manager);
 }
 
-class TestObserver : public InputMethodEngineInterface::Observer {
+class TestObserver : public ui::IMEEngineObserver {
  public:
   TestObserver() : calls_bitmap_(NONE) {}
   ~TestObserver() override {}
@@ -77,20 +78,20 @@
     calls_bitmap_ |= DEACTIVATED;
   }
   void OnFocus(
-      const InputMethodEngineInterface::InputContext& context) override {
+      const ui::IMEEngineHandlerInterface::InputContext& context) override {
     calls_bitmap_ |= ONFOCUS;
   }
   void OnBlur(int context_id) override { calls_bitmap_ |= ONBLUR; }
   bool IsInterestedInKeyEvent() const override { return true; }
-  void OnKeyEvent(const std::string& engine_id,
-                  const InputMethodEngineInterface::KeyboardEvent& event,
-                  input_method::KeyEventHandle* key_data) override {}
-  void OnInputContextUpdate(
-      const InputMethodEngineInterface::InputContext& context) override {}
-  void OnCandidateClicked(
+  void OnKeyEvent(
       const std::string& engine_id,
-      int candidate_id,
-      InputMethodEngineInterface::MouseButtonEvent button) override {}
+      const ui::IMEEngineHandlerInterface::KeyboardEvent& event,
+      ui::IMEEngineHandlerInterface::KeyEventDoneCallback& key_data) override {}
+  void OnInputContextUpdate(
+      const ui::IMEEngineHandlerInterface::InputContext& context) override {}
+  void OnCandidateClicked(const std::string& engine_id,
+                          int candidate_id,
+                          MouseButtonEvent button) override {}
   void OnMenuItemActivated(const std::string& engine_id,
                            const std::string& menu_id) override {}
   void OnSurroundingTextChanged(const std::string& engine_id,
@@ -116,7 +117,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestObserver);
 };
 
-class InputMethodEngineTest :  public testing::Test {
+class InputMethodEngineTest : public testing::Test {
  public:
   InputMethodEngineTest() : observer_(NULL), input_view_("inputview.html") {
     languages_.push_back("en-US");
@@ -137,7 +138,7 @@
   void CreateEngine(bool whitelisted) {
     engine_.reset(new InputMethodEngine());
     observer_ = new TestObserver();
-    scoped_ptr<InputMethodEngineInterface::Observer> observer_ptr(observer_);
+    scoped_ptr<ui::IMEEngineObserver> observer_ptr(observer_);
     engine_->Initialize(observer_ptr.Pass(),
                         whitelisted ? kTestExtensionId : kTestExtensionId2,
                         ProfileManager::GetActiveUserProfile());
@@ -240,7 +241,7 @@
   CreateEngine(true);
   FocusIn(ui::TEXT_INPUT_TYPE_TEXT);
   engine_->Enable(kTestImeComponentId);
-  std::vector<InputMethodEngineInterface::SegmentInfo> segments;
+  std::vector<ui::IMEEngineHandlerInterface::SegmentInfo> segments;
   int context = engine_->GetCotextIdForTesting();
   std::string error;
   base::HistogramTester histograms;
@@ -264,8 +265,7 @@
   std::vector<gfx::Rect> rects;
   rects.push_back(gfx::Rect());
   engine_->SetCompositionBounds(rects);
-  EXPECT_EQ(ONCOMPOSITIONBOUNDSCHANGED,
-            observer_->GetCallsBitmapAndReset());
+  EXPECT_EQ(ONCOMPOSITIONBOUNDSCHANGED, observer_->GetCallsBitmapAndReset());
 }
 
 }  // namespace input_method
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
index 4eaf6692..7f75d6b 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -23,7 +23,6 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h"
 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h"
-#include "chrome/browser/chromeos/input_method/input_method_engine.h"
 #include "chrome/browser/chromeos/input_method/input_method_switch_recorder.h"
 #include "chrome/browser/chromeos/language_preferences.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
@@ -446,7 +445,7 @@
 void InputMethodManagerImpl::StateImpl::AddInputMethodExtension(
     const std::string& extension_id,
     const InputMethodDescriptors& descriptors,
-    InputMethodEngineInterface* engine) {
+    ui::IMEEngineHandlerInterface* engine) {
   if (manager_->ui_session_ == STATE_TERMINATING)
     return;
 
@@ -975,7 +974,7 @@
 
   if (notify_menu) {
     // Clear property list.  Property list would be updated by
-    // extension IMEs via InputMethodEngine::(Set|Update)MenuItems.
+    // extension IMEs via IMEEngineHandlerInterface::(Set|Update)MenuItems.
     // If the current input method is a keyboard layout, empty
     // properties are sufficient.
     const ui::ime::InputMethodMenuItemList empty_menu_item_list;
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.h b/chrome/browser/chromeos/input_method/input_method_manager_impl.h
index 7b11c0db..8860afc 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl.h
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.h
@@ -17,6 +17,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 #include "ui/base/ime/chromeos/input_method_whitelist.h"
+#include "ui/base/ime/ime_engine_handler_interface.h"
+
+namespace ui {
+class IMEEngineHandlerInterface;
+}  // namespace ui
 
 namespace chromeos {
 class ComponentExtensionIMEManager;
@@ -71,9 +76,10 @@
 
     // InputMethodManager::State overrides.
     scoped_refptr<InputMethodManager::State> Clone() const override;
-    void AddInputMethodExtension(const std::string& extension_id,
-                                 const InputMethodDescriptors& descriptors,
-                                 InputMethodEngineInterface* instance) override;
+    void AddInputMethodExtension(
+        const std::string& extension_id,
+        const InputMethodDescriptors& descriptors,
+        ui::IMEEngineHandlerInterface* instance) override;
     void RemoveInputMethodExtension(const std::string& extension_id) override;
     void ChangeInputMethod(const std::string& input_method_id,
                            bool show_message) override;
@@ -254,7 +260,7 @@
   bool enable_extension_loading_;
 
   // The engine map from extension_id to an engine.
-  typedef std::map<std::string, InputMethodEngineInterface*> EngineMap;
+  typedef std::map<std::string, ui::IMEEngineHandlerInterface*> EngineMap;
   typedef std::map<Profile*, EngineMap, ProfileCompare> ProfileEngineMap;
   ProfileEngineMap engine_map_;
 
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
index 2b021b5..a91a3fe 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
 #include "chrome/browser/chromeos/input_method/mock_candidate_window_controller.h"
 #include "chrome/browser/chromeos/input_method/mock_input_method_engine.h"
 #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/chromeos/input_method/mock_input_method_engine.cc b/chrome/browser/chromeos/input_method/mock_input_method_engine.cc
index 852a0957..203527f 100644
--- a/chrome/browser/chromeos/input_method/mock_input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/mock_input_method_engine.cc
@@ -1,3 +1,4 @@
+
 // Copyright 2014 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
@@ -28,7 +29,7 @@
 }
 
 bool MockInputMethodEngine::ClearComposition(int context_id,
-                                             std::string* error)  {
+                                             std::string* error) {
   return true;
 }
 
@@ -50,8 +51,7 @@
 }
 
 void MockInputMethodEngine::SetCandidateWindowProperty(
-    const CandidateWindowProperty& property) {
-}
+    const CandidateWindowProperty& property) {}
 
 bool MockInputMethodEngine::SetCandidateWindowVisible(bool visible,
                                                       std::string* error) {
@@ -91,15 +91,12 @@
   return true;
 }
 
-void MockInputMethodEngine::HideInputView() {
-}
+void MockInputMethodEngine::HideInputView() {}
 
 void MockInputMethodEngine::FocusIn(
-    const IMEEngineHandlerInterface::InputContext& input_context) {
-}
+    const IMEEngineHandlerInterface::InputContext& input_context) {}
 
-void MockInputMethodEngine::FocusOut() {
-}
+void MockInputMethodEngine::FocusOut() {}
 
 void MockInputMethodEngine::Enable(const std::string& component_id) {
   active_component_id_ = component_id;
@@ -113,20 +110,16 @@
   last_activated_property_ = property_name;
 }
 
-void MockInputMethodEngine::Reset() {
-}
+void MockInputMethodEngine::Reset() {}
 
 bool MockInputMethodEngine::IsInterestedInKeyEvent() const {
   return true;
 }
 
-void MockInputMethodEngine::ProcessKeyEvent(
-    const ui::KeyEvent& key_event,
-    const KeyEventDoneCallback& callback) {
-}
+void MockInputMethodEngine::ProcessKeyEvent(const ui::KeyEvent& key_event,
+                                            KeyEventDoneCallback& callback) {}
 
-void MockInputMethodEngine::CandidateClicked(uint32 index) {
-}
+void MockInputMethodEngine::CandidateClicked(uint32 index) {}
 
 void MockInputMethodEngine::SetSurroundingText(const std::string& text,
                                                uint32 cursor_pos,
@@ -134,7 +127,6 @@
                                                uint32 offset_pos) {}
 
 void MockInputMethodEngine::SetCompositionBounds(
-    const std::vector<gfx::Rect>& bounds) {
-}
+    const std::vector<gfx::Rect>& bounds) {}
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/mock_input_method_engine.h b/chrome/browser/chromeos/input_method/mock_input_method_engine.h
index 5151d39..2aa3952d 100644
--- a/chrome/browser/chromeos/input_method/mock_input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/mock_input_method_engine.h
@@ -8,10 +8,11 @@
 #include <string>
 #include <vector>
 
-#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
 #include "ui/base/ime/chromeos/input_method_descriptor.h"
+#include "ui/base/ime/ime_engine_handler_interface.h"
 
 namespace ui {
+class IMEEngineHandlerInterface;
 class KeyEvent;
 
 namespace ime {
@@ -25,15 +26,14 @@
 
 namespace input_method {
 class CandidateWindow;
-struct KeyEventHandle;
 }
 
-class MockInputMethodEngine : public InputMethodEngineInterface {
+class MockInputMethodEngine : public ui::IMEEngineHandlerInterface {
  public:
   MockInputMethodEngine();
   ~MockInputMethodEngine() override;
 
-  // InputMethodEngineInterface overrides.
+  // IMEEngineHandlerInterface overrides.
   const std::string& GetActiveComponentId() const override;
   bool SetComposition(int context_id,
                       const char* text,
@@ -76,7 +76,7 @@
   void Reset() override;
   bool IsInterestedInKeyEvent() const override;
   void ProcessKeyEvent(const ui::KeyEvent& key_event,
-                       const KeyEventDoneCallback& callback) override;
+                       KeyEventDoneCallback& callback) override;
   void CandidateClicked(uint32 index) override;
   void SetSurroundingText(const std::string& text,
                           uint32 cursor_pos,
diff --git a/chrome/browser/chromeos/input_method/mock_input_method_manager.cc b/chrome/browser/chromeos/input_method/mock_input_method_manager.cc
index 7254bf91..ef233ac 100644
--- a/chrome/browser/chromeos/input_method/mock_input_method_manager.cc
+++ b/chrome/browser/chromeos/input_method/mock_input_method_manager.cc
@@ -116,8 +116,7 @@
 void MockInputMethodManager::State::AddInputMethodExtension(
     const std::string& extension_id,
     const InputMethodDescriptors& descriptors,
-    InputMethodEngineInterface* instance) {
-}
+    ui::IMEEngineHandlerInterface* instance) {}
 
 void MockInputMethodManager::State::RemoveInputMethodExtension(
     const std::string& extension_id) {
diff --git a/chrome/browser/chromeos/input_method/mock_input_method_manager.h b/chrome/browser/chromeos/input_method/mock_input_method_manager.h
index 7673045..3a41db1b 100644
--- a/chrome/browser/chromeos/input_method/mock_input_method_manager.h
+++ b/chrome/browser/chromeos/input_method/mock_input_method_manager.h
@@ -23,9 +23,10 @@
     explicit State(MockInputMethodManager* manager);
 
     scoped_refptr<InputMethodManager::State> Clone() const override;
-    void AddInputMethodExtension(const std::string& extension_id,
-                                 const InputMethodDescriptors& descriptors,
-                                 InputMethodEngineInterface* instance) override;
+    void AddInputMethodExtension(
+        const std::string& extension_id,
+        const InputMethodDescriptors& descriptors,
+        ui::IMEEngineHandlerInterface* instance) override;
     void RemoveInputMethodExtension(const std::string& extension_id) override;
     void ChangeInputMethod(const std::string& input_method_id,
                            bool show_message) override;
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc
index 6bbea04..281dee8c 100644
--- a/chrome/browser/chromeos/login/app_launch_controller.cc
+++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -15,7 +15,6 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/app_mode/startup_app_launcher.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.cc b/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.cc
index 1c62d43ac..3001eb4 100644
--- a/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.cc
+++ b/chrome/browser/chromeos/login/demo_mode/demo_app_launcher.cc
@@ -7,7 +7,6 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
-#include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
 #include "chrome/browser/extensions/component_loader.h"
@@ -98,7 +97,7 @@
   OpenApplication(
       AppLaunchParams(profile, extension, extensions::LAUNCH_CONTAINER_WINDOW,
                       NEW_WINDOW, extensions::SOURCE_CHROME_INTERNAL));
-  InitAppSession(profile, extension_id);
+  KioskAppManager::Get()->InitSession(profile, extension_id);
 
   user_manager::UserManager::Get()->SessionStarted();
 
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index 6c88365..25f1e7d 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -437,8 +437,9 @@
 
   // Click on 'cancel'.
   content::DOMMessageQueue message_queue;  // Observe before 'cancel'.
-  ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(),
-                                     "$('close-button-item').click();"));
+  ASSERT_TRUE(
+      content::ExecuteScript(GetLoginUI()->GetWebContents(),
+                             "$('gaia-navigation').$.closeButton.click();"));
 
   // Auth flow should change back to Gaia.
   std::string message;
diff --git a/chrome/browser/chromeos/login/screens/error_screen.cc b/chrome/browser/chromeos/login/screens/error_screen.cc
index 8ce8c30f..fa900f93 100644
--- a/chrome/browser/chromeos/login/screens/error_screen.cc
+++ b/chrome/browser/chromeos/login/screens/error_screen.cc
@@ -10,7 +10,6 @@
 #include "base/logging.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/app_mode/app_session_lifetime.h"
 #include "chrome/browser/chromeos/app_mode/certificate_manager_dialog.h"
 #include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
@@ -281,7 +280,7 @@
   OpenApplication(
       AppLaunchParams(profile, extension, extensions::LAUNCH_CONTAINER_WINDOW,
                       NEW_WINDOW, extensions::SOURCE_CHROME_INTERNAL));
-  InitAppSession(profile, extension_id);
+  KioskAppManager::Get()->InitSession(profile, extension_id);
 
   user_manager::UserManager::Get()->SessionStarted();
 
diff --git a/chrome/browser/chromeos/login/webview_login_browsertest.cc b/chrome/browser/chromeos/login/webview_login_browsertest.cc
index c509a804..93009ca 100644
--- a/chrome/browser/chromeos/login/webview_login_browsertest.cc
+++ b/chrome/browser/chromeos/login/webview_login_browsertest.cc
@@ -28,12 +28,12 @@
 IN_PROC_BROWSER_TEST_F(WebviewLoginTest, Basic) {
   WaitForGaiaPageLoad();
 
-  JsExpect("$('close-button-item').hidden");
+  JsExpect("!$('gaia-navigation').closeVisible");
 
   SetSignFormField("identifier", OobeBaseTest::kFakeUserEmail);
   ExecuteJsInSigninFrame("document.getElementById('nextButton').click();");
 
-  JsExpect("$('close-button-item').hidden");
+  JsExpect("!$('gaia-navigation').closeVisible");
 
   content::WindowedNotificationObserver session_start_waiter(
       chrome::NOTIFICATION_SESSION_STARTED,
@@ -50,24 +50,25 @@
   WaitForGaiaPageLoad();
 
   // Start: no back button, first page.
-  JsExpect("$('back-button-item').hidden");
+  JsExpect("!$('gaia-navigation').backVisible");
   JsExpect("$('signin-frame').src.indexOf('#identifier') != -1");
 
   // Next step: back button active, second page.
   SetSignFormField("identifier", OobeBaseTest::kFakeUserEmail);
   ExecuteJsInSigninFrame("document.getElementById('nextButton').click();");
-  JsExpect("!$('back-button-item').hidden");
+  JsExpect("$('gaia-navigation').backVisible");
   JsExpect("$('signin-frame').src.indexOf('#challengepassword') != -1");
 
   // One step back: no back button, first page.
-  ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(),
-                                     "$('back-button-item').click();"));
-  JsExpect("$('back-button-item').hidden");
+  ASSERT_TRUE(
+      content::ExecuteScript(GetLoginUI()->GetWebContents(),
+                             "$('gaia-navigation').$.backButton.click();"));
+  JsExpect("!$('gaia-navigation').backVisible");
   JsExpect("$('signin-frame').src.indexOf('#identifier') != -1");
 
   // Next step (again): back button active, second page, user id remembered.
   ExecuteJsInSigninFrame("document.getElementById('nextButton').click();");
-  JsExpect("!$('back-button-item').hidden");
+  JsExpect("$('gaia-navigation').backVisible");
   JsExpect("$('signin-frame').src.indexOf('#challengepassword') != -1");
 
   content::WindowedNotificationObserver session_start_waiter(
diff --git a/chrome/browser/chromeos/options/wifi_config_view.cc b/chrome/browser/chromeos/options/wifi_config_view.cc
index f246182..c3197f8 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.cc
+++ b/chrome/browser/chromeos/options/wifi_config_view.cc
@@ -900,8 +900,10 @@
   const NetworkState* network = GetNetworkState();
   if (network) {
     if (network->type() == shill::kTypeWifi) {
-      if (network->security_class() == shill::kSecurity8021x)
+      if (network->security_class() == shill::kSecurity8021x ||
+          network->IsDynamicWep()) {
         show_8021x = true;
+      }
     } else if (network->type() == shill::kTypeEthernet) {
       show_8021x = true;
     } else {
diff --git a/chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc b/chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc
index 45b96c33..6c81f18 100644
--- a/chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc
+++ b/chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.cc
@@ -110,7 +110,8 @@
 
 void PolicyOAuth2TokenFetcher::OnClientOAuthFailure(
     const GoogleServiceAuthError& error) {
-  VLOG(1) << "OAuth2 tokens fetch for policy fetch failed!";
+  VLOG(1) << "OAuth2 tokens fetch for policy fetch failed! (error = "
+          << error.state() << ")";
   RetryOnError(error,
                base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingRefreshToken,
                           AsWeakPtr()));
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc
index 88936630..af11c91 100644
--- a/chrome/browser/chromeos/preferences_unittest.cc
+++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -100,7 +100,7 @@
     void AddInputMethodExtension(
         const std::string& id,
         const InputMethodDescriptors& descriptors,
-        InputMethodEngineInterface* instance) override {
+        ui::IMEEngineHandlerInterface* instance) override {
       InputMethodDescriptor descriptor(
           id, std::string(), std::string(), std::vector<std::string>(),
           std::vector<std::string>(), false, GURL(), GURL());
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.cc b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
index f61155c..48b6aee 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.cc
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
@@ -180,6 +180,14 @@
 void DeviceSettingsTestHelper::GetServerBackedStateKeys(
     const StateKeysCallback& callback) {}
 
+void DeviceSettingsTestHelper::CheckArcAvailability(
+    const ArcCallback& callback) {}
+
+void DeviceSettingsTestHelper::StartArcInstance(const std::string& socket_path,
+                                                const ArcCallback& callback) {}
+
+void DeviceSettingsTestHelper::StopArcInstance(const ArcCallback& callback) {}
+
 DeviceSettingsTestHelper::PolicyState::PolicyState()
     : store_result_(true) {}
 
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.h b/chrome/browser/chromeos/settings/device_settings_test_helper.h
index 565116a..b191eb9b 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.h
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.h
@@ -119,6 +119,11 @@
                        const std::vector<std::string>& flags) override;
   void GetServerBackedStateKeys(const StateKeysCallback& callback) override;
 
+  void CheckArcAvailability(const ArcCallback& callback) override;
+  void StartArcInstance(const std::string& socket_path,
+                        const ArcCallback& callback) override;
+  void StopArcInstance(const ArcCallback& callback) override;
+
  private:
   struct PolicyState {
     bool store_result_;
diff --git a/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc b/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
index 0d5d585..68c26a77 100644
--- a/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
+++ b/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
@@ -192,6 +192,7 @@
                      &Delegate::SetDevicesUpdatesEnabled, delegate);
   d->RegisterHandler("performActionOnRemotePage",
                      &Delegate::PerformActionOnRemotePage, delegate);
+  d->RegisterHandler("openRemotePage", &Delegate::OpenRemotePage, delegate);
   d->RegisterHandler("dispatchProtocolMessage",
                      &Delegate::DispatchProtocolMessageFromDevToolsFrontend,
                      delegate);
diff --git a/chrome/browser/devtools/devtools_embedder_message_dispatcher.h b/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
index 35300818..cddc540 100644
--- a/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
+++ b/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
@@ -72,6 +72,8 @@
         const std::string& port_forwarding_config) = 0;
     virtual void PerformActionOnRemotePage(const std::string& page_id,
                                            const std::string& action) = 0;
+    virtual void OpenRemotePage(const std::string& browser_id,
+                                const std::string& url) = 0;
     virtual void GetPreferences(const DispatchCallback& callback) = 0;
     virtual void SetPreference(const std::string& name,
                                const std::string& value) = 0;
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index 66ff96fb..ce151fb 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -848,6 +848,13 @@
     target->Close();
 }
 
+void DevToolsUIBindings::OpenRemotePage(const std::string& browser_id,
+                                        const std::string& url) {
+  if (!remote_targets_handler_)
+    return;
+  remote_targets_handler_->Open(browser_id, url);
+}
+
 void DevToolsUIBindings::GetPreferences(const DispatchCallback& callback) {
   const DictionaryValue* prefs =
       profile_->GetPrefs()->GetDictionary(prefs::kDevToolsPreferences);
diff --git a/chrome/browser/devtools/devtools_ui_bindings.h b/chrome/browser/devtools/devtools_ui_bindings.h
index e44545b3..18bb409 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.h
+++ b/chrome/browser/devtools/devtools_ui_bindings.h
@@ -130,6 +130,8 @@
   void SetDevicesUpdatesEnabled(bool enabled) override;
   void PerformActionOnRemotePage(const std::string& page_id,
                                  const std::string& action) override;
+  void OpenRemotePage(const std::string& browser_id,
+                      const std::string& url) override;
   void DispatchProtocolMessageFromDevToolsFrontend(
       const std::string& message) override;
   void RecordEnumeratedHistogram(const std::string& name,
diff --git a/chrome/browser/engagement/site_engagement_helper.cc b/chrome/browser/engagement/site_engagement_helper.cc
index 8da594f1..4e9ac8d 100644
--- a/chrome/browser/engagement/site_engagement_helper.cc
+++ b/chrome/browser/engagement/site_engagement_helper.cc
@@ -14,54 +14,62 @@
 
 namespace {
 
-int g_seconds_between_user_input_check = 10;
-int g_seconds_tracking_delay_after_navigation = 10;
-int g_seconds_tracking_delay_after_show = 5;
+int g_seconds_to_pause_engagement_detection = 10;
+int g_seconds_delay_after_navigation = 10;
+int g_seconds_delay_after_show = 5;
 
 }  // anonymous namespace
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SiteEngagementHelper);
 
-SiteEngagementHelper::InputTracker::InputTracker(
-    content::WebContents* web_contents,
+SiteEngagementHelper::PeriodicTracker::PeriodicTracker(
     SiteEngagementHelper* helper)
-    : WebContentsObserver(web_contents),
-      helper_(helper),
-      pause_timer_(new base::Timer(true, false)),
-      is_tracking_(false) {}
+    : helper_(helper), pause_timer_(new base::Timer(true, false)) {}
 
-SiteEngagementHelper::InputTracker::~InputTracker() {}
+SiteEngagementHelper::PeriodicTracker::~PeriodicTracker() {}
 
-void SiteEngagementHelper::InputTracker::Start(base::TimeDelta initial_delay) {
+void SiteEngagementHelper::PeriodicTracker::Start(
+    base::TimeDelta initial_delay) {
   StartTimer(initial_delay);
 }
 
-void SiteEngagementHelper::InputTracker::Pause() {
-  is_tracking_ = false;
-  StartTimer(base::TimeDelta::FromSeconds(g_seconds_between_user_input_check));
+void SiteEngagementHelper::PeriodicTracker::Pause() {
+  TrackingStopped();
+  StartTimer(
+      base::TimeDelta::FromSeconds(g_seconds_to_pause_engagement_detection));
 }
 
-void SiteEngagementHelper::InputTracker::Stop() {
-  is_tracking_ = false;
+void SiteEngagementHelper::PeriodicTracker::Stop() {
+  TrackingStopped();
   pause_timer_->Stop();
 }
 
-void SiteEngagementHelper::InputTracker::SetPauseTimerForTesting(
+void SiteEngagementHelper::PeriodicTracker::SetPauseTimerForTesting(
     scoped_ptr<base::Timer> timer) {
   pause_timer_ = timer.Pass();
 }
 
-void SiteEngagementHelper::InputTracker::StartTimer(base::TimeDelta delay) {
+void SiteEngagementHelper::PeriodicTracker::StartTimer(
+    base::TimeDelta delay) {
   pause_timer_->Start(
       FROM_HERE, delay,
-      base::Bind(&SiteEngagementHelper::InputTracker::StartTracking,
+      base::Bind(&SiteEngagementHelper::PeriodicTracker::TrackingStarted,
                  base::Unretained(this)));
 }
 
-void SiteEngagementHelper::InputTracker::StartTracking() {
+SiteEngagementHelper::InputTracker::InputTracker(
+    SiteEngagementHelper* helper,
+    content::WebContents* web_contents)
+    : PeriodicTracker(helper), content::WebContentsObserver(web_contents) {}
+
+void SiteEngagementHelper::InputTracker::TrackingStarted() {
   is_tracking_ = true;
 }
 
+void SiteEngagementHelper::InputTracker::TrackingStopped() {
+  is_tracking_ = false;
+}
+
 // Record that there was some user input, and defer handling of the input event.
 // Once the timer finishes running, the callbacks detecting user input will be
 // registered again.
@@ -77,13 +85,17 @@
   // compiler verifying that all cases are covered).
   switch (type) {
     case blink::WebInputEvent::RawKeyDown:
-      helper_->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
+      helper()->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
       break;
     case blink::WebInputEvent::MouseDown:
-      helper_->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_MOUSE);
+      helper()->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_MOUSE);
       break;
     case blink::WebInputEvent::GestureTapDown:
-      helper_->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE);
+      helper()->RecordUserInput(
+          SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE);
+      break;
+    case blink::WebInputEvent::MouseWheel:
+      helper()->RecordUserInput(SiteEngagementMetrics::ENGAGEMENT_WHEEL);
       break;
     default:
       NOTREACHED();
@@ -91,15 +103,48 @@
   Pause();
 }
 
+SiteEngagementHelper::MediaTracker::MediaTracker(
+    SiteEngagementHelper* helper,
+    content::WebContents* web_contents)
+    : PeriodicTracker(helper), content::WebContentsObserver(web_contents),
+      is_hidden_(false),
+      is_playing_(false) {}
+
+void SiteEngagementHelper::MediaTracker::TrackingStarted() {
+  if (is_playing_)
+    helper()->RecordMediaPlaying(is_hidden_);
+
+  Pause();
+}
+
+void SiteEngagementHelper::MediaTracker::MediaStartedPlaying() {
+  is_playing_ = true;
+}
+
+void SiteEngagementHelper::MediaTracker::MediaPaused() {
+  is_playing_ = false;
+}
+
+void SiteEngagementHelper::MediaTracker::WasShown() {
+  is_hidden_ = false;
+}
+
+void SiteEngagementHelper::MediaTracker::WasHidden() {
+  is_hidden_ = true;
+}
+
 SiteEngagementHelper::~SiteEngagementHelper() {
   content::WebContents* contents = web_contents();
-  if (contents)
+  if (contents) {
     input_tracker_.Stop();
+    media_tracker_.Stop();
+  }
 }
 
 SiteEngagementHelper::SiteEngagementHelper(content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
-      input_tracker_(web_contents, this),
+      input_tracker_(this, web_contents),
+      media_tracker_(this, web_contents),
       record_engagement_(false) {}
 
 void SiteEngagementHelper::RecordUserInput(
@@ -118,10 +163,24 @@
   }
 }
 
+void SiteEngagementHelper::RecordMediaPlaying(bool is_hidden) {
+  content::WebContents* contents = web_contents();
+  if (contents) {
+    Profile* profile =
+        Profile::FromBrowserContext(contents->GetBrowserContext());
+    SiteEngagementService* service =
+        SiteEngagementServiceFactory::GetForProfile(profile);
+
+    if (service)
+      service->HandleMediaPlaying(contents->GetVisibleURL(), is_hidden);
+  }
+}
+
 void SiteEngagementHelper::DidNavigateMainFrame(
     const content::LoadCommittedDetails& details,
     const content::FrameNavigateParams& params) {
   input_tracker_.Stop();
+  media_tracker_.Stop();
 
   record_engagement_ = params.url.SchemeIsHTTPOrHTTPS();
 
@@ -137,15 +196,19 @@
   if (service)
     service->HandleNavigation(params.url, params.transition);
 
-  input_tracker_.Start(
-      base::TimeDelta::FromSeconds(g_seconds_tracking_delay_after_navigation));
+  base::TimeDelta delay =
+      base::TimeDelta::FromSeconds(g_seconds_delay_after_navigation);
+  input_tracker_.Start(delay);
+  media_tracker_.Start(delay);
 }
 
 void SiteEngagementHelper::WasShown() {
   // Ensure that the input callbacks are registered when we come into view.
   if (record_engagement_) {
-    input_tracker_.Start(
-        base::TimeDelta::FromSeconds(g_seconds_tracking_delay_after_show));
+    base::TimeDelta delay =
+        base::TimeDelta::FromSeconds(g_seconds_delay_after_show);
+    input_tracker_.Start(delay);
+    media_tracker_.Start(delay);
   }
 }
 
@@ -156,15 +219,15 @@
 
 // static
 void SiteEngagementHelper::SetSecondsBetweenUserInputCheck(int seconds) {
-  g_seconds_between_user_input_check = seconds;
+  g_seconds_to_pause_engagement_detection = seconds;
 }
 
 // static
 void SiteEngagementHelper::SetSecondsTrackingDelayAfterNavigation(int seconds) {
-  g_seconds_tracking_delay_after_navigation = seconds;
+  g_seconds_delay_after_navigation = seconds;
 }
 
 // static
 void SiteEngagementHelper::SetSecondsTrackingDelayAfterShow(int seconds) {
-  g_seconds_tracking_delay_after_show = seconds;
+  g_seconds_delay_after_show = seconds;
 }
diff --git a/chrome/browser/engagement/site_engagement_helper.h b/chrome/browser/engagement/site_engagement_helper.h
index 9ba1807..3c0ca26 100644
--- a/chrome/browser/engagement/site_engagement_helper.h
+++ b/chrome/browser/engagement/site_engagement_helper.h
@@ -37,22 +37,19 @@
   void WasHidden() override;
 
  private:
-  // Class to encapsulate the user input listening.
+  // Class to encapsulate the periodic detection of site engagement.
   //
-  // Time on site is recorded by detecting any user input (mouse click,
-  // keypress, or touch gesture tap) per some discrete time unit. If there is
-  // user input, then record a positive site engagement.
+  // All engagement detection begins at some constant time delta following
+  // navigation or tab activation. Once engagement is recorded, detection is
+  // suspended for another constant time delta. For sites to continually record
+  // engagement, this overall design requires:
   //
-  // When input is detected, SiteEngagementHelper::RecordUserInput is called,
-  // and the input detection callbacks are paused for
-  // g_seconds_between_user_input_check. This ensures that there is minimal
-  // overhead in input listening, and that input over an extended length of time
-  // is required to continually increase the engagement score.
-  class InputTracker : public content::WebContentsObserver {
+  // 1. engagement at a non-trivial time after a site loads
+  // 2. continual engagement over a non-trivial length of time
+  class PeriodicTracker {
    public:
-    explicit InputTracker(content::WebContents* web_contents,
-                          SiteEngagementHelper* helper);
-    ~InputTracker() override;
+    explicit PeriodicTracker(SiteEngagementHelper* helper);
+    virtual ~PeriodicTracker();
 
     // Begin tracking input after |initial_delay|.
     void Start(base::TimeDelta initial_delay);
@@ -63,28 +60,88 @@
     // Stop listening for user input.
     void Stop();
 
-    // Returns whether the tracker will respond to user input via
-    // DidGetUserInteraction.
-    bool is_tracking() const { return is_tracking_; }
-
     // Set the timer object for testing purposes.
     void SetPauseTimerForTesting(scoped_ptr<base::Timer> timer);
 
+    SiteEngagementHelper* helper() { return helper_; }
+
+   protected:
+    friend class SiteEngagementHelperTest;
+
+    // Called when tracking is to be paused by |delay|. Used when tracking first
+    // starts or is paused.
+    void StartTimer(base::TimeDelta delay);
+
+    // Called when the timer expires and engagement tracking is activated.
+    virtual void TrackingStarted() {}
+
+    // Called when engagement tracking is paused or stopped.
+    virtual void TrackingStopped() {}
+
+   private:
+    SiteEngagementHelper* helper_;
+    scoped_ptr<base::Timer> pause_timer_;
+  };
+
+  // Class to encapsulate time-on-site engagement detection. Time-on-site is
+  // recorded by detecting user input on a focused WebContents (mouse click,
+  // mouse wheel, keypress, or touch gesture tap) over time.
+  //
+  // After an initial delay, the input tracker begins listening to
+  // DidGetUserInteraction. When user input is signaled, site engagement is
+  // recorded, and the tracker sleeps for
+  // |g_seconds_to_pause_engagement_detection|.
+  class InputTracker : public PeriodicTracker,
+                       public content::WebContentsObserver {
+   public:
+    InputTracker(SiteEngagementHelper* helper,
+                 content::WebContents* web_contents);
+
+    bool is_tracking() const { return is_tracking_; }
+
    private:
     friend class SiteEngagementHelperTest;
 
-    // Starts the timer for detecting user interaction.
-    void StartTimer(base::TimeDelta delay);
+    void TrackingStarted() override;
+    void TrackingStopped() override;
 
-    // Callback for StartTimer that activates the user input tracking.
-    void StartTracking();
+    // Returns whether the tracker will respond to user input via
+    // DidGetUserInteraction.
+    bool is_tracking_;
 
     // content::WebContentsObserver overrides.
     void DidGetUserInteraction(const blink::WebInputEvent::Type type) override;
+  };
 
-    SiteEngagementHelper* helper_;
-    scoped_ptr<base::Timer> pause_timer_;
-    bool is_tracking_;
+  // Class to encapsulate media detection. Any media playing in a WebContents
+  // (focused or not) will accumulate engagement points. Media in a hidden
+  // WebContents will accumulate engagement more slowly than in an active
+  // WebContents. Media which has been muted will also accumulate engagement
+  // more slowly.
+  //
+  // The tracker continually notes the visible/hidden state of the WebContents
+  // that it observes, as well as whether media is playing. After an initial
+  // delay, the tracker wakes up every |g_seconds_to_pause_engagement_detection|
+  // and records engagement if media is currently playing.
+  class MediaTracker : public PeriodicTracker,
+                       public content::WebContentsObserver {
+   public:
+    MediaTracker(SiteEngagementHelper* helper,
+                 content::WebContents* web_contents);
+
+   private:
+    friend class SiteEngagementHelperTest;
+
+    void TrackingStarted() override;
+
+    // content::WebContentsObserver overrides.
+    void MediaStartedPlaying() override;
+    void MediaPaused() override;
+    void WasShown() override;
+    void WasHidden() override;
+
+    bool is_hidden_;
+    bool is_playing_;
   };
 
   explicit SiteEngagementHelper(content::WebContents* web_contents);
@@ -92,10 +149,15 @@
   friend class SiteEngagementHelperTest;
 
   // Ask the SiteEngagementService to record engagement via user input at the
-  // current contents location.
+  // current WebContents URL.
   void RecordUserInput(SiteEngagementMetrics::EngagementType type);
 
+  // Ask the SiteEngagementService to record engagement via media playing at the
+  // current WebContents URL.
+  void RecordMediaPlaying(bool is_hidden);
+
   InputTracker input_tracker_;
+  MediaTracker media_tracker_;
   bool record_engagement_;
 
   DISALLOW_COPY_AND_ASSIGN(SiteEngagementHelper);
diff --git a/chrome/browser/engagement/site_engagement_helper_unittest.cc b/chrome/browser/engagement/site_engagement_helper_unittest.cc
index 92789f8..4297d45d 100644
--- a/chrome/browser/engagement/site_engagement_helper_unittest.cc
+++ b/chrome/browser/engagement/site_engagement_helper_unittest.cc
@@ -29,8 +29,9 @@
     return helper.Pass();
   }
 
-  void StartTracking(SiteEngagementHelper* helper) {
-    helper->input_tracker_.StartTracking();
+  void TrackingStarted(SiteEngagementHelper* helper) {
+    helper->input_tracker_.TrackingStarted();
+    helper->media_tracker_.TrackingStarted();
   }
 
   // Simulate a user interaction event and handle it.
@@ -42,9 +43,21 @@
   // Simulate a user interaction event and handle it. Reactivates tracking
   // immediately.
   void HandleUserInputAndRestartTracking(SiteEngagementHelper* helper,
-                       blink::WebInputEvent::Type type) {
+                                         blink::WebInputEvent::Type type) {
     helper->input_tracker_.DidGetUserInteraction(type);
-    helper->input_tracker_.StartTracking();
+    helper->input_tracker_.TrackingStarted();
+  }
+
+  void HandleMediaPlaying(SiteEngagementHelper* helper, bool is_hidden) {
+    helper->RecordMediaPlaying(is_hidden);
+  }
+
+  void MediaStartedPlaying(SiteEngagementHelper* helper) {
+    helper->media_tracker_.MediaStartedPlaying();
+  }
+
+  void MediaPaused(SiteEngagementHelper* helper) {
+    helper->media_tracker_.MediaPaused();
   }
 
   // Set a pause timer on the input tracker for test purposes.
@@ -80,7 +93,7 @@
 
     // Check that navigation triggers engagement.
     NavigateWithDisposition(url1, CURRENT_TAB);
-    StartTracking(helper.get());
+    TrackingStarted(helper.get());
 
     EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
     EXPECT_EQ(0, service->GetScore(url2));
@@ -101,7 +114,7 @@
 
     // Simulate inputs for a different link.
     NavigateWithDisposition(url2, CURRENT_TAB);
-    StartTracking(helper.get());
+    TrackingStarted(helper.get());
 
     EXPECT_DOUBLE_EQ(0.7, service->GetScore(url1));
     EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
@@ -118,14 +131,93 @@
   UserInputAccumulation(blink::WebInputEvent::RawKeyDown);
 }
 
-TEST_F(SiteEngagementHelperTest, MouseEventEngagementAccumulation) {
+TEST_F(SiteEngagementHelperTest, MouseDownEventEngagementAccumulation) {
   UserInputAccumulation(blink::WebInputEvent::MouseDown);
 }
 
+TEST_F(SiteEngagementHelperTest, MouseWheelEventEngagementAccumulation) {
+  UserInputAccumulation(blink::WebInputEvent::MouseWheel);
+}
+
 TEST_F(SiteEngagementHelperTest, GestureEngagementAccumulation) {
   UserInputAccumulation(blink::WebInputEvent::GestureTapDown);
 }
 
+TEST_F(SiteEngagementHelperTest, MediaEngagementAccumulation) {
+  AddTab(browser(), GURL("about:blank"));
+  GURL url1("https://www.google.com/");
+  GURL url2("http://www.google.com/");
+  content::WebContents* web_contents =
+    browser()->tab_strip_model()->GetActiveWebContents();
+
+  scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
+  SiteEngagementService* service =
+    SiteEngagementServiceFactory::GetForProfile(browser()->profile());
+  DCHECK(service);
+
+  NavigateWithDisposition(url1, CURRENT_TAB);
+  TrackingStarted(helper.get());
+
+  EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+
+  // Simulate a foreground media input and ensure it is treated correctly.
+  HandleMediaPlaying(helper.get(), false);
+
+  EXPECT_DOUBLE_EQ(0.52, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+
+  // Simulate continual media playing, and ensure it is treated correctly.
+  HandleMediaPlaying(helper.get(), false);
+  HandleMediaPlaying(helper.get(), false);
+  HandleMediaPlaying(helper.get(), false);
+
+  EXPECT_DOUBLE_EQ(0.58, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+
+  // Simulate backgrounding the media.
+  HandleMediaPlaying(helper.get(), true);
+  HandleMediaPlaying(helper.get(), true);
+
+  EXPECT_DOUBLE_EQ(0.60, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+
+  // Simulate inputs for a different link.
+  NavigateWithDisposition(url2, CURRENT_TAB);
+  TrackingStarted(helper.get());
+
+  EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
+  EXPECT_DOUBLE_EQ(1.1, service->GetTotalEngagementPoints());
+
+  HandleMediaPlaying(helper.get(), false);
+  HandleMediaPlaying(helper.get(), false);
+  EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.54, service->GetScore(url2));
+  EXPECT_DOUBLE_EQ(1.14, service->GetTotalEngagementPoints());
+}
+
+TEST_F(SiteEngagementHelperTest, MediaEngagement) {
+  AddTab(browser(), GURL("about:blank"));
+  GURL url1("https://www.google.com/");
+  GURL url2("http://www.google.com/");
+  content::WebContents* web_contents =
+    browser()->tab_strip_model()->GetActiveWebContents();
+
+  scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
+  SiteEngagementService* service =
+    SiteEngagementServiceFactory::GetForProfile(browser()->profile());
+  DCHECK(service);
+
+  NavigateWithDisposition(url1, CURRENT_TAB);
+  // Start media playing before tracking begins
+  MediaStartedPlaying(helper.get());
+  TrackingStarted(helper.get());
+
+  EXPECT_DOUBLE_EQ(0.52, service->GetScore(url1));
+  EXPECT_EQ(0, service->GetScore(url2));
+}
+
 TEST_F(SiteEngagementHelperTest, MixedInputEngagementAccumulation) {
   AddTab(browser(), GURL("about:blank"));
   GURL url1("https://www.google.com/");
@@ -145,7 +237,7 @@
                               0);
 
   NavigateWithDisposition(url1, CURRENT_TAB);
-  StartTracking(helper.get());
+  TrackingStarted(helper.get());
 
   EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
   EXPECT_EQ(0, service->GetScore(url2));
@@ -180,39 +272,49 @@
                                2);
 
   HandleUserInputAndRestartTracking(helper.get(),
-                                    blink::WebInputEvent::MouseDown);
+                                    blink::WebInputEvent::MouseWheel);
   HandleUserInputAndRestartTracking(helper.get(),
                                     blink::WebInputEvent::MouseDown);
+  HandleMediaPlaying(helper.get(), true);
   HandleUserInputAndRestartTracking(helper.get(),
                                     blink::WebInputEvent::GestureTapDown);
+  HandleMediaPlaying(helper.get(), false);
 
-  EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.93, service->GetScore(url1));
   EXPECT_EQ(0, service->GetScore(url2));
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              9);
+                              11);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 3);
+                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 2);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_WHEEL, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE,
                                3);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE,
+                               1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN,
+                               1);
 
   NavigateWithDisposition(url2, CURRENT_TAB);
-  StartTracking(helper.get());
+  TrackingStarted(helper.get());
 
-  EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.93, service->GetScore(url1));
   EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
-  EXPECT_DOUBLE_EQ(1.4, service->GetTotalEngagementPoints());
+  EXPECT_DOUBLE_EQ(1.43, service->GetTotalEngagementPoints());
 
   HandleUserInputAndRestartTracking(helper.get(),
                                     blink::WebInputEvent::GestureTapDown);
   HandleUserInputAndRestartTracking(helper.get(),
                                     blink::WebInputEvent::RawKeyDown);
 
-  EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
+  EXPECT_DOUBLE_EQ(0.93, service->GetScore(url1));
   EXPECT_DOUBLE_EQ(0.6, service->GetScore(url2));
-  EXPECT_DOUBLE_EQ(1.5, service->GetTotalEngagementPoints());
+  EXPECT_DOUBLE_EQ(1.53, service->GetTotalEngagementPoints());
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              12);
+                              14);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 2);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
diff --git a/chrome/browser/engagement/site_engagement_metrics.h b/chrome/browser/engagement/site_engagement_metrics.h
index 143ec5e..f4eaa7f 100644
--- a/chrome/browser/engagement/site_engagement_metrics.h
+++ b/chrome/browser/engagement/site_engagement_metrics.h
@@ -21,6 +21,9 @@
     ENGAGEMENT_KEYPRESS,
     ENGAGEMENT_MOUSE,
     ENGAGEMENT_TOUCH_GESTURE,
+    ENGAGEMENT_WHEEL,
+    ENGAGEMENT_MEDIA_HIDDEN,
+    ENGAGEMENT_MEDIA_VISIBLE,
     ENGAGEMENT_LAST,
   };
 
diff --git a/chrome/browser/engagement/site_engagement_service.cc b/chrome/browser/engagement/site_engagement_service.cc
index 8d85ffc..95e01c9 100644
--- a/chrome/browser/engagement/site_engagement_service.cc
+++ b/chrome/browser/engagement/site_engagement_service.cc
@@ -35,6 +35,8 @@
 const char kMaxPointsPerDayParam[] = "max_points_per_day";
 const char kNavigationPointsParam[] = "navigation_points";
 const char kUserInputPointsParam[] = "user_input_points";
+const char kVisibleMediaPlayingPointsParam[] = "visible_media_playing_points";
+const char kHiddenMediaPlayingPointsParam[] = "hidden_media_playing_points";
 const char kDecayPeriodInDaysParam[] = "decay_period_in_days";
 const char kDecayPointsParam[] = "decay_points";
 
@@ -102,6 +104,8 @@
 double SiteEngagementScore::g_max_points_per_day = 5;
 double SiteEngagementScore::g_navigation_points = 0.5;
 double SiteEngagementScore::g_user_input_points = 0.05;
+double SiteEngagementScore::g_visible_media_playing_points = 0.02;
+double SiteEngagementScore::g_hidden_media_playing_points = 0.01;
 int SiteEngagementScore::g_decay_period_in_days = 7;
 double SiteEngagementScore::g_decay_points = 5;
 
@@ -116,23 +120,39 @@
       SiteEngagementService::kEngagementParams, kNavigationPointsParam);
   std::string user_input_points_param = variations::GetVariationParamValue(
       SiteEngagementService::kEngagementParams, kUserInputPointsParam);
+  std::string visible_media_playing_points_param =
+      variations::GetVariationParamValue(
+          SiteEngagementService::kEngagementParams,
+          kVisibleMediaPlayingPointsParam);
+  std::string hidden_media_playing_points_param =
+      variations::GetVariationParamValue(
+          SiteEngagementService::kEngagementParams,
+          kHiddenMediaPlayingPointsParam);
   std::string decay_period_in_days_param = variations::GetVariationParamValue(
       SiteEngagementService::kEngagementParams, kDecayPeriodInDaysParam);
   std::string decay_points_param = variations::GetVariationParamValue(
       SiteEngagementService::kEngagementParams, kDecayPointsParam);
 
   if (!max_points_per_day_param.empty() && !navigation_points_param.empty() &&
-      !user_input_points_param.empty() && !decay_period_in_days_param.empty() &&
-      !decay_points_param.empty()) {
+      !user_input_points_param.empty() &&
+      !visible_media_playing_points_param.empty() &&
+      !hidden_media_playing_points_param.empty() &&
+      !decay_period_in_days_param.empty() && !decay_points_param.empty()) {
     double max_points_per_day = 0;
     double navigation_points = 0;
     double user_input_points = 0;
+    double visible_media_playing_points = 0;
+    double hidden_media_playing_points = 0;
     int decay_period_in_days = 0;
     double decay_points = 0;
 
     if (base::StringToDouble(max_points_per_day_param, &max_points_per_day) &&
         base::StringToDouble(navigation_points_param, &navigation_points) &&
         base::StringToDouble(user_input_points_param, &user_input_points) &&
+        base::StringToDouble(visible_media_playing_points_param,
+                             &visible_media_playing_points) &&
+        base::StringToDouble(hidden_media_playing_points_param,
+                             &hidden_media_playing_points) &&
         base::StringToInt(decay_period_in_days_param, &decay_period_in_days) &&
         base::StringToDouble(decay_points_param, &decay_points) &&
         max_points_per_day >= navigation_points &&
@@ -142,6 +162,8 @@
       g_max_points_per_day = max_points_per_day;
       g_navigation_points = navigation_points;
       g_user_input_points = user_input_points;
+      g_visible_media_playing_points = visible_media_playing_points;
+      g_hidden_media_playing_points = hidden_media_playing_points;
       g_decay_period_in_days = decay_period_in_days;
       g_decay_points = decay_points;
     }
@@ -324,6 +346,17 @@
   RecordMetrics();
 }
 
+void SiteEngagementService::HandleMediaPlaying(const GURL& url,
+                                               bool is_hidden) {
+  SiteEngagementMetrics::RecordEngagement(
+      is_hidden ? SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN
+                : SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE);
+  AddPoints(url, is_hidden
+                     ? SiteEngagementScore::g_hidden_media_playing_points
+                     : SiteEngagementScore::g_visible_media_playing_points);
+  RecordMetrics();
+}
+
 double SiteEngagementService::GetScore(const GURL& url) {
   HostContentSettingsMap* settings_map =
     HostContentSettingsMapFactory::GetForProfile(profile_);
diff --git a/chrome/browser/engagement/site_engagement_service.h b/chrome/browser/engagement/site_engagement_service.h
index 36b1fd2..85dca08 100644
--- a/chrome/browser/engagement/site_engagement_service.h
+++ b/chrome/browser/engagement/site_engagement_service.h
@@ -38,6 +38,14 @@
   // The number of points given for user input (indicating time-on-site).
   static double g_user_input_points;
 
+  // The number of points given for media playing. Initially calibrated such
+  // that at least 30 minutes of video watching or audio listening would be
+  // required to allow a site to reach the daily engagement maximum.
+  static double g_visible_media_playing_points;
+
+  // The number of points given for media playing in a non-visible tab.
+  static double g_hidden_media_playing_points;
+
   // Decaying works by removing a portion of the score periodically. This
   // constant determines how often that happens.
   static int g_decay_period_in_days;
@@ -149,6 +157,11 @@
   void HandleUserInput(const GURL& url,
                        SiteEngagementMetrics::EngagementType type);
 
+  // Update the karma score of the origin matching |url| for media playing. The
+  // points awarded are discounted if the media is being played in a non-visible
+  // tab.
+  void HandleMediaPlaying(const GURL& url, bool is_hidden);
+
   // Overridden from SiteEngagementScoreProvider:
   double GetScore(const GURL& url) override;
   double GetTotalEngagementPoints() override;
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc
index 3debc8a..e182598 100644
--- a/chrome/browser/engagement/site_engagement_service_unittest.cc
+++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
@@ -506,6 +506,13 @@
   service->HandleUserInput(url1, SiteEngagementMetrics::ENGAGEMENT_MOUSE);
   EXPECT_DOUBLE_EQ(0.15, service->GetScore(url1));
   EXPECT_DOUBLE_EQ(0.3, service->GetTotalEngagementPoints());
+
+  service->HandleUserInput(url2, SiteEngagementMetrics::ENGAGEMENT_WHEEL);
+  service->HandleUserInput(url3,
+                           SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE);
+  EXPECT_DOUBLE_EQ(0.15, service->GetScore(url2));
+  EXPECT_DOUBLE_EQ(0.1, service->GetScore(url3));
+  EXPECT_DOUBLE_EQ(0.4, service->GetTotalEngagementPoints());
 }
 
 TEST_F(SiteEngagementServiceTest, CheckHistograms) {
@@ -546,6 +553,7 @@
   service->HandleNavigation(url1, ui::PAGE_TRANSITION_TYPED);
   service->HandleUserInput(url1, SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
   service->HandleUserInput(url1, SiteEngagementMetrics::ENGAGEMENT_MOUSE);
+  service->HandleMediaPlaying(url2, true);
 
   histograms.ExpectTotalCount(SiteEngagementMetrics::kTotalEngagementHistogram,
                               1);
@@ -565,13 +573,16 @@
   histograms.ExpectUniqueSample(
       SiteEngagementMetrics::kPercentOriginsWithMaxEngagementHistogram, 0, 1);
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              3);
+                              4);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_MOUSE, 1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN,
+                               1);
 
   clock->SetNow(GetReferenceTime() + base::TimeDelta::FromMinutes(59));
 
@@ -579,18 +590,23 @@
   service->HandleNavigation(url2, ui::PAGE_TRANSITION_AUTO_BOOKMARK);
 
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              5);
+                              6);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 3);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_MOUSE, 1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN,
+                               1);
 
   clock->SetNow(GetReferenceTime() + base::TimeDelta::FromMinutes(60));
 
   service->HandleNavigation(url3, ui::PAGE_TRANSITION_TYPED);
-  service->HandleUserInput(url2, SiteEngagementMetrics::ENGAGEMENT_MOUSE);
+  service->HandleUserInput(url2,
+                           SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE);
+  service->HandleMediaPlaying(url3, false);
 
   histograms.ExpectTotalCount(SiteEngagementMetrics::kTotalEngagementHistogram,
                               2);
@@ -612,28 +628,42 @@
   histograms.ExpectUniqueSample(
       SiteEngagementMetrics::kPercentOriginsWithMaxEngagementHistogram, 0, 2);
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              7);
+                              9);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 4);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 1);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 2);
+                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE,
+                               1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_VISIBLE,
+                               1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_MEDIA_HIDDEN,
+                               1);
 
   service->HandleNavigation(url1, ui::PAGE_TRANSITION_GENERATED);
   service->HandleNavigation(url1, ui::PAGE_TRANSITION_TYPED);
-  service->HandleUserInput(url2, SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
+  service->HandleUserInput(url2, SiteEngagementMetrics::ENGAGEMENT_WHEEL);
   service->HandleUserInput(url1, SiteEngagementMetrics::ENGAGEMENT_KEYPRESS);
   service->HandleUserInput(url3, SiteEngagementMetrics::ENGAGEMENT_MOUSE);
 
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              12);
+                              14);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 6);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 3);
+                               SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 2);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 3);
+                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 2);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_TOUCH_GESTURE,
+                               1);
+  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
+                               SiteEngagementMetrics::ENGAGEMENT_WHEEL, 1);
 
   // Advance an origin to the max for a day and advance the clock an hour before
   // the last increment before max. Expect the histogram to be updated.
@@ -664,14 +694,10 @@
   histograms.ExpectUniqueSample(
       SiteEngagementMetrics::kPercentOriginsWithMaxEngagementHistogram, 0, 3);
   histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                              19);
+                              21);
   histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
                                SiteEngagementMetrics::ENGAGEMENT_NAVIGATION,
                                13);
-  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 3);
-  histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
-                               SiteEngagementMetrics::ENGAGEMENT_MOUSE, 3);
 }
 
 // Expect that sites that have reached zero engagement are cleaned up.
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
index 8b0de986..d357cd4 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -24,6 +24,8 @@
 #include "ui/base/ime/chromeos/component_extension_ime_manager.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
+#include "ui/base/ime/ime_engine_handler_interface.h"
+#include "ui/base/ime/text_input_flags.h"
 
 namespace input_ime = extensions::api::input_ime;
 namespace KeyEventHandled = extensions::api::input_ime::KeyEventHandled;
@@ -40,7 +42,7 @@
 namespace CommitText = extensions::api::input_ime::CommitText;
 namespace ClearComposition = extensions::api::input_ime::ClearComposition;
 namespace SetComposition = extensions::api::input_ime::SetComposition;
-using chromeos::InputMethodEngineInterface;
+using ui::IMEEngineHandlerInterface;
 
 namespace {
 
@@ -51,41 +53,33 @@
     "inputMethodPrivate.onCompositionBoundsChanged";
 
 void SetMenuItemToMenu(const input_ime::MenuItem& input,
-                       InputMethodEngineInterface::MenuItem* out) {
+                       IMEEngineHandlerInterface::MenuItem* out) {
   out->modified = 0;
   out->id = input.id;
   if (input.label) {
-    out->modified |= InputMethodEngineInterface::MENU_ITEM_MODIFIED_LABEL;
+    out->modified |= IMEEngineHandlerInterface::MENU_ITEM_MODIFIED_LABEL;
     out->label = *input.label;
   }
 
   if (input.style != input_ime::MENU_ITEM_STYLE_NONE) {
-    out->modified |= InputMethodEngineInterface::MENU_ITEM_MODIFIED_STYLE;
-    out->style = static_cast<InputMethodEngineInterface::MenuItemStyle>(
-        input.style);
+    out->modified |= IMEEngineHandlerInterface::MENU_ITEM_MODIFIED_STYLE;
+    out->style =
+        static_cast<IMEEngineHandlerInterface::MenuItemStyle>(input.style);
   }
 
   if (input.visible)
-    out->modified |= InputMethodEngineInterface::MENU_ITEM_MODIFIED_VISIBLE;
+    out->modified |= IMEEngineHandlerInterface::MENU_ITEM_MODIFIED_VISIBLE;
   out->visible = input.visible ? *input.visible : true;
 
   if (input.checked)
-    out->modified |= InputMethodEngineInterface::MENU_ITEM_MODIFIED_CHECKED;
+    out->modified |= IMEEngineHandlerInterface::MENU_ITEM_MODIFIED_CHECKED;
   out->checked = input.checked ? *input.checked : false;
 
   if (input.enabled)
-    out->modified |= InputMethodEngineInterface::MENU_ITEM_MODIFIED_ENABLED;
+    out->modified |= IMEEngineHandlerInterface::MENU_ITEM_MODIFIED_ENABLED;
   out->enabled = input.enabled ? *input.enabled : true;
 }
 
-void CallbackKeyEventHandle(chromeos::input_method::KeyEventHandle* key_data,
-                            bool handled) {
-  base::Callback<void(bool consumed)>* callback =
-      reinterpret_cast<base::Callback<void(bool consumed)>*>(key_data);
-  callback->Run(handled);
-  delete callback;
-}
-
 extensions::InputImeEventRouter* GetInputImeEventRouter(Profile* profile) {
   if (profile->HasOffTheRecordProfile())
     profile = profile->GetOffTheRecordProfile();
@@ -96,7 +90,7 @@
 }  // namespace
 
 namespace chromeos {
-class ImeObserver : public InputMethodEngineInterface::Observer {
+class ImeObserver : public ui::IMEEngineObserver {
  public:
   explicit ImeObserver(const std::string& extension_id, Profile* profile)
       : extension_id_(extension_id), profile_(profile) {}
@@ -129,16 +123,17 @@
   }
 
   void OnFocus(
-      const InputMethodEngineInterface::InputContext& context) override {
+      const IMEEngineHandlerInterface::InputContext& context) override {
     if (extension_id_.empty() || !HasListener(input_ime::OnFocus::kEventName))
       return;
 
     input_ime::InputContext context_value;
     context_value.context_id = context.id;
-    context_value.type = input_ime::ParseInputContextType(context.type);
-    context_value.auto_correct = context.auto_correct;
-    context_value.auto_complete = context.auto_complete;
-    context_value.spell_check = context.spell_check;
+    context_value.type =
+        input_ime::ParseInputContextType(ConvertInputContextType(context));
+    context_value.auto_correct = ConvertInputContextAutoCorrect(context);
+    context_value.auto_complete = ConvertInputContextAutoComplete(context);
+    context_value.spell_check = ConvertInputContextSpellCheck(context);
 
     scoped_ptr<base::ListValue> args(input_ime::OnFocus::Create(context_value));
 
@@ -157,14 +152,15 @@
   }
 
   void OnInputContextUpdate(
-      const InputMethodEngineInterface::InputContext& context) override {
+      const IMEEngineHandlerInterface::InputContext& context) override {
     if (extension_id_.empty() ||
         !HasListener(input_ime::OnInputContextUpdate::kEventName))
       return;
 
     input_ime::InputContext context_value;
     context_value.context_id = context.id;
-    context_value.type = input_ime::ParseInputContextType(context.type);
+    context_value.type =
+        input_ime::ParseInputContextType(ConvertInputContextType(context));
 
     scoped_ptr<base::ListValue> args(
         input_ime::OnInputContextUpdate::Create(context_value));
@@ -178,9 +174,10 @@
     return ShouldForwardKeyEvent();
   }
 
-  void OnKeyEvent(const std::string& component_id,
-                  const InputMethodEngineInterface::KeyboardEvent& event,
-                  chromeos::input_method::KeyEventHandle* key_data) override {
+  void OnKeyEvent(
+      const std::string& component_id,
+      const IMEEngineHandlerInterface::KeyboardEvent& event,
+      IMEEngineHandlerInterface::KeyEventDoneCallback& key_data) override {
     if (extension_id_.empty())
       return;
 
@@ -189,7 +186,7 @@
     if (!ShouldForwardKeyEvent()) {
       // Continue processing the key event so that the physical keyboard can
       // still work.
-      CallbackKeyEventHandle(key_data, false);
+      key_data.Run(false);
       return;
     }
 
@@ -218,22 +215,22 @@
   void OnCandidateClicked(
       const std::string& component_id,
       int candidate_id,
-      InputMethodEngineInterface::MouseButtonEvent button) override {
+      ui::IMEEngineObserver::MouseButtonEvent button) override {
     if (extension_id_.empty() ||
         !HasListener(input_ime::OnCandidateClicked::kEventName))
       return;
 
     input_ime::MouseButton button_enum = input_ime::MOUSE_BUTTON_NONE;
     switch (button) {
-      case InputMethodEngineInterface::MOUSE_BUTTON_MIDDLE:
+      case ui::IMEEngineObserver::MOUSE_BUTTON_MIDDLE:
         button_enum = input_ime::MOUSE_BUTTON_MIDDLE;
         break;
 
-      case InputMethodEngineInterface::MOUSE_BUTTON_RIGHT:
+      case ui::IMEEngineObserver::MOUSE_BUTTON_RIGHT:
         button_enum = input_ime::MOUSE_BUTTON_RIGHT;
         break;
 
-      case InputMethodEngineInterface::MOUSE_BUTTON_LEFT:
+      case ui::IMEEngineObserver::MOUSE_BUTTON_LEFT:
       // Default to left.
       default:
         button_enum = input_ime::MOUSE_BUTTON_LEFT;
@@ -327,6 +324,50 @@
                              input_ime::OnReset::kEventName, args.Pass());
   }
 
+  std::string ConvertInputContextType(
+      ui::IMEEngineHandlerInterface::InputContext input_context) {
+    std::string input_context_type = "text";
+    switch (input_context.type) {
+      case ui::TEXT_INPUT_TYPE_SEARCH:
+        input_context_type = "search";
+        break;
+      case ui::TEXT_INPUT_TYPE_TELEPHONE:
+        input_context_type = "tel";
+        break;
+      case ui::TEXT_INPUT_TYPE_URL:
+        input_context_type = "url";
+        break;
+      case ui::TEXT_INPUT_TYPE_EMAIL:
+        input_context_type = "email";
+        break;
+      case ui::TEXT_INPUT_TYPE_NUMBER:
+        input_context_type = "number";
+        break;
+      case ui::TEXT_INPUT_TYPE_PASSWORD:
+        input_context_type = "password";
+        break;
+      default:
+        input_context_type = "text";
+        break;
+    }
+    return input_context_type;
+  }
+
+  bool ConvertInputContextAutoCorrect(
+      ui::IMEEngineHandlerInterface::InputContext input_context) {
+    return !(input_context.flags & ui::TEXT_INPUT_FLAG_AUTOCORRECT_OFF);
+  }
+
+  bool ConvertInputContextAutoComplete(
+      ui::IMEEngineHandlerInterface::InputContext input_context) {
+    return !(input_context.flags & ui::TEXT_INPUT_FLAG_AUTOCOMPLETE_OFF);
+  }
+
+  bool ConvertInputContextSpellCheck(
+      ui::IMEEngineHandlerInterface::InputContext input_context) {
+    return !(input_context.flags & ui::TEXT_INPUT_FLAG_SPELLCHECK_OFF);
+  }
+
  private:
   void DispatchEventToExtension(
       extensions::events::HistogramValue histogram_value,
@@ -488,7 +529,7 @@
     }
   }
 
-  scoped_ptr<chromeos::InputMethodEngineInterface::Observer> observer(
+  scoped_ptr<ui::IMEEngineObserver> observer(
       new chromeos::ImeObserver(extension_id, profile_));
   chromeos::InputMethodEngine* engine = new chromeos::InputMethodEngine();
   engine->Initialize(observer.Pass(), extension_id.c_str(), profile_);
@@ -501,7 +542,7 @@
 }
 
 void InputImeEventRouter::UnregisterAllImes(const std::string& extension_id) {
-  std::map<std::string, InputMethodEngineInterface*>::iterator it =
+  std::map<std::string, IMEEngineHandlerInterface*>::iterator it =
       engine_map_.find(extension_id);
   if (it != engine_map_.end()) {
     chromeos::input_method::InputMethodManager::Get()
@@ -512,19 +553,19 @@
   }
 }
 
-InputMethodEngineInterface* InputImeEventRouter::GetEngine(
+IMEEngineHandlerInterface* InputImeEventRouter::GetEngine(
     const std::string& extension_id,
     const std::string& component_id) {
-  std::map<std::string, InputMethodEngineInterface*>::iterator it =
+  std::map<std::string, IMEEngineHandlerInterface*>::iterator it =
       engine_map_.find(extension_id);
   if (it != engine_map_.end())
     return it->second;
   return NULL;
 }
 
-InputMethodEngineInterface* InputImeEventRouter::GetActiveEngine(
+IMEEngineHandlerInterface* InputImeEventRouter::GetActiveEngine(
     const std::string& extension_id) {
-  std::map<std::string, InputMethodEngineInterface*>::iterator it =
+  std::map<std::string, IMEEngineHandlerInterface*>::iterator it =
       engine_map_.find(extension_id);
   if (it != engine_map_.end() && it->second->IsActive())
     return it->second;
@@ -542,15 +583,13 @@
   }
 
   std::string component_id = request->second.first;
-  chromeos::input_method::KeyEventHandle* key_data = request->second.second;
+  (request->second.second).Run(handled);
   request_map_.erase(request);
-
-  CallbackKeyEventHandle(key_data, handled);
 }
 
 std::string InputImeEventRouter::AddRequest(
     const std::string& component_id,
-    chromeos::input_method::KeyEventHandle* key_data) {
+    IMEEngineHandlerInterface::KeyEventDoneCallback& key_data) {
   std::string request_id = base::IntToString(next_request_id_);
   ++next_request_id_;
 
@@ -560,7 +599,7 @@
 }
 
 bool InputImeSetCompositionFunction::RunSync() {
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetActiveEngine(extension_id());
   if (!engine) {
@@ -571,7 +610,7 @@
   scoped_ptr<SetComposition::Params> parent_params(
       SetComposition::Params::Create(*args_));
   const SetComposition::Params::Parameters& params = parent_params->parameters;
-  std::vector<InputMethodEngineInterface::SegmentInfo> segments;
+  std::vector<IMEEngineHandlerInterface::SegmentInfo> segments;
   if (params.segments) {
     const std::vector<linked_ptr<
         SetComposition::Params::Parameters::SegmentsType> >&
@@ -580,20 +619,20 @@
       EXTENSION_FUNCTION_VALIDATE(
           segments_args[i]->style !=
           input_ime::UNDERLINE_STYLE_NONE);
-      segments.push_back(InputMethodEngineInterface::SegmentInfo());
+      segments.push_back(IMEEngineHandlerInterface::SegmentInfo());
       segments.back().start = segments_args[i]->start;
       segments.back().end = segments_args[i]->end;
       if (segments_args[i]->style ==
           input_ime::UNDERLINE_STYLE_UNDERLINE) {
         segments.back().style =
-            InputMethodEngineInterface::SEGMENT_STYLE_UNDERLINE;
+            IMEEngineHandlerInterface::SEGMENT_STYLE_UNDERLINE;
       } else if (segments_args[i]->style ==
                  input_ime::UNDERLINE_STYLE_DOUBLEUNDERLINE) {
         segments.back().style =
-            InputMethodEngineInterface::SEGMENT_STYLE_DOUBLE_UNDERLINE;
+            IMEEngineHandlerInterface::SEGMENT_STYLE_DOUBLE_UNDERLINE;
       } else {
         segments.back().style =
-            InputMethodEngineInterface::SEGMENT_STYLE_NO_UNDERLINE;
+            IMEEngineHandlerInterface::SEGMENT_STYLE_NO_UNDERLINE;
       }
     }
   }
@@ -611,7 +650,7 @@
 }
 
 bool InputImeClearCompositionFunction::RunSync() {
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetActiveEngine(extension_id());
   if (!engine) {
@@ -630,7 +669,7 @@
 }
 
 bool InputImeCommitTextFunction::RunSync() {
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetActiveEngine(extension_id());
   if (!engine) {
@@ -649,7 +688,7 @@
 }
 
 bool InputImeHideInputViewFunction::RunAsync() {
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetActiveEngine(extension_id());
   if (!engine) {
@@ -664,7 +703,7 @@
       SendKeyEvents::Params::Create(*args_));
   const SendKeyEvents::Params::Parameters& params =
       parent_params->parameters;
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetActiveEngine(extension_id());
   if (!engine) {
@@ -674,10 +713,10 @@
 
   const std::vector<linked_ptr<input_ime::KeyboardEvent> >& key_data =
       params.key_data;
-  std::vector<chromeos::InputMethodEngineInterface::KeyboardEvent> key_data_out;
+  std::vector<IMEEngineHandlerInterface::KeyboardEvent> key_data_out;
 
   for (size_t i = 0; i < key_data.size(); ++i) {
-    chromeos::InputMethodEngineInterface::KeyboardEvent event;
+    IMEEngineHandlerInterface::KeyboardEvent event;
     event.type = input_ime::ToString(key_data[i]->type);
     event.key = key_data[i]->key;
     event.code = key_data[i]->code;
@@ -703,7 +742,7 @@
   const SetCandidateWindowProperties::Params::Parameters&
       params = parent_params->parameters;
 
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetEngine(extension_id(), params.engine_id);
   if (!engine) {
@@ -720,8 +759,8 @@
     return true;
   }
 
-  InputMethodEngineInterface::CandidateWindowProperty properties_out =
-    engine->GetCandidateWindowProperty();
+  IMEEngineHandlerInterface::CandidateWindowProperty properties_out =
+      engine->GetCandidateWindowProperty();
   bool modified = false;
 
   if (properties.cursor_visible) {
@@ -768,7 +807,7 @@
 }
 
 bool InputImeSetCandidatesFunction::RunSync() {
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetActiveEngine(extension_id());
   if (!engine) {
@@ -781,12 +820,12 @@
   const SetCandidates::Params::Parameters& params =
       parent_params->parameters;
 
-  std::vector<InputMethodEngineInterface::Candidate> candidates_out;
+  std::vector<IMEEngineHandlerInterface::Candidate> candidates_out;
   const std::vector<linked_ptr<
       SetCandidates::Params::Parameters::CandidatesType> >& candidates_in =
           params.candidates;
   for (size_t i = 0; i < candidates_in.size(); ++i) {
-    candidates_out.push_back(InputMethodEngineInterface::Candidate());
+    candidates_out.push_back(IMEEngineHandlerInterface::Candidate());
     candidates_out.back().value = candidates_in[i]->candidate;
     candidates_out.back().id = candidates_in[i]->id;
     if (candidates_in[i]->label)
@@ -805,7 +844,7 @@
 }
 
 bool InputImeSetCursorPositionFunction::RunSync() {
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetActiveEngine(extension_id());
   if (!engine) {
@@ -830,7 +869,7 @@
   const SetMenuItems::Params::Parameters& params =
       parent_params->parameters;
 
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetEngine(extension_id(), params.engine_id);
   if (!engine) {
@@ -839,10 +878,10 @@
   }
 
   const std::vector<linked_ptr<input_ime::MenuItem> >& items = params.items;
-  std::vector<InputMethodEngineInterface::MenuItem> items_out;
+  std::vector<IMEEngineHandlerInterface::MenuItem> items_out;
 
   for (size_t i = 0; i < items.size(); ++i) {
-    items_out.push_back(InputMethodEngineInterface::MenuItem());
+    items_out.push_back(IMEEngineHandlerInterface::MenuItem());
     SetMenuItemToMenu(*items[i], &items_out.back());
   }
 
@@ -857,7 +896,7 @@
   const UpdateMenuItems::Params::Parameters& params =
       parent_params->parameters;
 
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetEngine(extension_id(), params.engine_id);
   if (!engine) {
@@ -866,10 +905,10 @@
   }
 
   const std::vector<linked_ptr<input_ime::MenuItem> >& items = params.items;
-  std::vector<InputMethodEngineInterface::MenuItem> items_out;
+  std::vector<IMEEngineHandlerInterface::MenuItem> items_out;
 
   for (size_t i = 0; i < items.size(); ++i) {
-    items_out.push_back(InputMethodEngineInterface::MenuItem());
+    items_out.push_back(IMEEngineHandlerInterface::MenuItem());
     SetMenuItemToMenu(*items[i], &items_out.back());
   }
 
@@ -884,7 +923,7 @@
   const DeleteSurroundingText::Params::Parameters& params =
       parent_params->parameters;
 
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()))
           ->GetEngine(extension_id(), params.engine_id);
   if (!engine) {
@@ -950,7 +989,7 @@
 void InputImeAPI::OnListenerAdded(const EventListenerInfo& details) {
   if (!details.browser_context)
     return;
-  InputMethodEngineInterface* engine =
+  IMEEngineHandlerInterface* engine =
       GetInputImeEventRouter(
           Profile::FromBrowserContext(details.browser_context))
           ->GetActiveEngine(details.extension_id);
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.h b/chrome/browser/extensions/api/input_ime/input_ime_api.h
index de640b1..031a359 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.h
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.h
@@ -12,7 +12,6 @@
 #include "base/memory/singleton.h"
 #include "base/scoped_observer.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
@@ -20,13 +19,15 @@
 #include "extensions/browser/extension_function.h"
 #include "extensions/browser/extension_registry_observer.h"
 #include "extensions/common/extension.h"
+#include "ui/base/ime/ime_engine_handler_interface.h"
+#include "ui/base/ime/ime_engine_observer.h"
 
 class Profile;
 
-namespace chromeos {
-class InputMethodEngineInterface;
-class ImeObserver;
-}  // namespace chromeos
+namespace ui {
+class IMEEngineHandlerInterface;
+class IMEEngineObserver;
+}  // namespace ui
 
 namespace extensions {
 class ExtensionRegistry;
@@ -42,27 +43,29 @@
       const std::vector<extensions::InputComponentInfo>& input_components);
   void UnregisterAllImes(const std::string& extension_id);
 
-  chromeos::InputMethodEngineInterface* GetEngine(
-      const std::string& extension_id,
-      const std::string& component_id);
-  chromeos::InputMethodEngineInterface* GetActiveEngine(
+  ui::IMEEngineHandlerInterface* GetEngine(const std::string& extension_id,
+                                           const std::string& component_id);
+  ui::IMEEngineHandlerInterface* GetActiveEngine(
       const std::string& extension_id);
 
-
   // Called when a key event was handled.
   void OnKeyEventHandled(const std::string& extension_id,
                          const std::string& request_id,
                          bool handled);
 
-  std::string AddRequest(const std::string& component_id,
-                         chromeos::input_method::KeyEventHandle* key_data);
+  std::string AddRequest(
+      const std::string& component_id,
+      ui::IMEEngineHandlerInterface::KeyEventDoneCallback& key_data);
 
  private:
-  typedef std::map<std::string, std::pair<std::string,
-          chromeos::input_method::KeyEventHandle*> > RequestMap;
+  typedef std::map<
+      std::string,
+      std::pair<std::string,
+                ui::IMEEngineHandlerInterface::KeyEventDoneCallback>>
+      RequestMap;
 
   // The engine map from extension_id to an engine.
-  std::map<std::string, chromeos::InputMethodEngineInterface*> engine_map_;
+  std::map<std::string, ui::IMEEngineHandlerInterface*> engine_map_;
 
   unsigned int next_request_id_;
   RequestMap request_map_;
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc
index 06e5571..cd2b4b6 100644
--- a/chrome/browser/extensions/api/tabs/tabs_test.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -47,6 +47,11 @@
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_observer.h"
 
+#if defined(OS_MACOSX)
+#include "base/mac/mac_util.h"
+#include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
+#endif
+
 namespace extensions {
 
 namespace keys = tabs_constants;
@@ -1049,6 +1054,14 @@
 #endif  // !defined(OS_MACOSX)
 
 IN_PROC_BROWSER_TEST_F(ExtensionWindowCreateTest, AcceptState) {
+#if defined(OS_MACOSX)
+  // ScopedFakeNSWindowFullscreen works on MacOS 10.7+.
+  if (base::mac::IsOSSnowLeopard())
+    return;
+
+  ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
+#endif
+
   scoped_refptr<WindowsCreateFunction> function(new WindowsCreateFunction());
   scoped_refptr<Extension> extension(test_util::CreateEmptyExtension());
   function->set_extension(extension.get());
@@ -1068,8 +1081,6 @@
   EXPECT_TRUE(new_window->window()->IsMinimized());
 #endif
 
-// TODO(limasdf): Flaky on mac. See http://crbug.com/482433.
-#if !defined(OS_MACOSX)
   function = new WindowsCreateFunction();
   function->set_extension(extension.get());
   result.reset(utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
@@ -1080,7 +1091,9 @@
                                                         window_id, &error);
   EXPECT_TRUE(error.empty());
   EXPECT_TRUE(new_window->window()->IsFullscreen());
-#endif  // !defined(OS_MACOSX)
+
+  // Let the message loop run so that |fake_fullscreen| finishes transition.
+  content::RunAllPendingInMessageLoop();
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionWindowCreateTest, ValidateCreateWindowState) {
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc
index 3321e784..58e2c35 100644
--- a/chrome/browser/extensions/crx_installer_browsertest.cc
+++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/web_application_info.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/browser_thread.h"
@@ -43,6 +44,7 @@
 #include "extensions/common/permissions/permission_set.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "extensions/common/switches.h"
+#include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/l10n/l10n_util.h"
 
 #if defined(OS_CHROMEOS)
@@ -54,6 +56,14 @@
 
 class SkBitmap;
 
+namespace {
+
+const char kAppUrl[] = "http://www.google.com";
+const char kAppTitle[] = "Test title";
+const char kAppDescription[] = "Test description";
+
+}  // anonymous namespace
+
 namespace extensions {
 
 namespace {
@@ -98,6 +108,35 @@
   base::string16 error_;
 };
 
+SkBitmap CreateSquareBitmap(int size) {
+  SkBitmap bitmap;
+  bitmap.allocN32Pixels(size, size);
+  bitmap.eraseColor(SK_ColorRED);
+  return bitmap;
+}
+
+WebApplicationInfo::IconInfo CreateIconInfoWithBitmap(int size) {
+  WebApplicationInfo::IconInfo icon_info;
+  icon_info.width = size;
+  icon_info.height = size;
+  icon_info.data = CreateSquareBitmap(size);
+  return icon_info;
+}
+
+WebApplicationInfo CreateWebAppInfo(const char* title,
+                                    const char* description,
+                                    const char* app_url,
+                                    int size) {
+  WebApplicationInfo web_app_info;
+  web_app_info.title = base::UTF8ToUTF16(title);
+  web_app_info.description = base::UTF8ToUTF16(description);
+  web_app_info.app_url = GURL(app_url);
+
+  web_app_info.icons.push_back(CreateIconInfoWithBitmap(size));
+
+  return web_app_info;
+}
+
 class MockInstallPrompt : public ExtensionInstallPrompt {
  public:
   MockInstallPrompt(content::WebContents* web_contents,
@@ -266,6 +305,29 @@
     CHECK(!crx_path.empty()) << "Extension not found at " << test_path.value();
     return crx_path;
   }
+
+  void InstallWebAppAndVerifyNoErrors() {
+    ExtensionService* service =
+        extensions::ExtensionSystem::Get(browser()->profile())
+            ->extension_service();
+    scoped_refptr<CrxInstaller> crx_installer(
+        CrxInstaller::CreateSilent(service));
+    crx_installer->set_error_on_unsupported_requirements(true);
+    crx_installer->InstallWebApp(
+        CreateWebAppInfo(kAppTitle, kAppDescription, kAppUrl, 64));
+    EXPECT_TRUE(WaitForCrxInstallerDone());
+    ASSERT_TRUE(crx_installer->extension());
+    ASSERT_FALSE(HasRequirementErrors(crx_installer.get()));
+    ASSERT_FALSE(HasPolicyErrors(crx_installer.get()));
+  }
+
+  bool HasRequirementErrors(CrxInstaller* crx_installer) {
+    return !crx_installer->install_checker_.requirement_errors().empty();
+  }
+
+  bool HasPolicyErrors(CrxInstaller* crx_installer) {
+    return !crx_installer->install_checker_.policy_error().empty();
+  }
 };
 
 // This test is skipped on ChromeOS because it requires the NPAPI,
@@ -598,4 +660,21 @@
   EXPECT_FALSE(InstallExtension(crx_path, 0));
 }
 
+IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallWebApp) {
+  InstallWebAppAndVerifyNoErrors();
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
+                       InstallWebAppSucceedsWithBlockPolicy) {
+  // Verify that the install still works when a management policy blocking
+  // extension installation is in force. Bookmark apps are special-cased to skip
+  // these checks (see https://crbug.com/545541).
+  ManagementPolicyMock policy;
+  extensions::ExtensionSystem::Get(profile())
+      ->management_policy()
+      ->RegisterProvider(&policy);
+
+  InstallWebAppAndVerifyNoErrors();
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/dev_mode_bubble_controller.h b/chrome/browser/extensions/dev_mode_bubble_controller.h
deleted file mode 100644
index 6257b8d..0000000
--- a/chrome/browser/extensions/dev_mode_bubble_controller.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_DEV_MODE_BUBBLE_CONTROLLER_H_
-#define CHROME_BROWSER_EXTENSIONS_DEV_MODE_BUBBLE_CONTROLLER_H_
-
-#include <string>
-
-#include "chrome/browser/extensions/extension_message_bubble_controller.h"
-
-namespace extensions {
-
-class Extension;
-
-class DevModeBubbleController : public ExtensionMessageBubbleController {
- public:
-  // Clears the list of profiles the bubble has been shown for. Should only be
-  // used during testing.
-  static void ClearProfileListForTesting();
-
-  explicit DevModeBubbleController(Browser* browser);
-  ~DevModeBubbleController() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DevModeBubbleController);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_DEV_MODE_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/extensions/dev_mode_bubble_controller.cc b/chrome/browser/extensions/dev_mode_bubble_delegate.cc
similarity index 63%
rename from chrome/browser/extensions/dev_mode_bubble_controller.cc
rename to chrome/browser/extensions/dev_mode_bubble_delegate.cc
index 1ffee58..5f723de 100644
--- a/chrome/browser/extensions/dev_mode_bubble_controller.cc
+++ b/chrome/browser/extensions/dev_mode_bubble_delegate.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/extensions/dev_mode_bubble_controller.h"
+#include "chrome/browser/extensions/dev_mode_bubble_delegate.h"
 
 #include "base/lazy_instance.h"
 #include "base/metrics/histogram.h"
@@ -24,40 +24,7 @@
 base::LazyInstance<std::set<Profile*> > g_shown_for_profiles =
     LAZY_INSTANCE_INITIALIZER;
 
-////////////////////////////////////////////////////////////////////////////////
-// DevModeBubbleDelegate
-
-class DevModeBubbleDelegate
-    : public ExtensionMessageBubbleController::Delegate {
- public:
-  explicit DevModeBubbleDelegate(Profile* profile);
-  ~DevModeBubbleDelegate() override;
-
-  // ExtensionMessageBubbleController::Delegate methods.
-  bool ShouldIncludeExtension(const Extension* extension) override;
-  void AcknowledgeExtension(
-      const std::string& extension_id,
-      ExtensionMessageBubbleController::BubbleAction user_action) override;
-  void PerformAction(const ExtensionIdList& list) override;
-  base::string16 GetTitle() const override;
-  base::string16 GetMessageBody(bool anchored_to_browser_action,
-                                int extension_count) const override;
-  base::string16 GetOverflowText(
-      const base::string16& overflow_count) const override;
-  GURL GetLearnMoreUrl() const override;
-  base::string16 GetActionButtonLabel() const override;
-  base::string16 GetDismissButtonLabel() const override;
-  bool ShouldShowExtensionList() const override;
-  bool ShouldHighlightExtensions() const override;
-  bool ShouldLimitToEnabledExtensions() const override;
-  void LogExtensionCount(size_t count) override;
-  void LogAction(
-      ExtensionMessageBubbleController::BubbleAction action) override;
-  std::set<Profile*>* GetProfileSet() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DevModeBubbleDelegate);
-};
+}  // namespace
 
 DevModeBubbleDelegate::DevModeBubbleDelegate(Profile* profile)
     : ExtensionMessageBubbleController::Delegate(profile) {
@@ -110,6 +77,10 @@
   return l10n_util::GetStringUTF16(IDS_CANCEL);
 }
 
+bool DevModeBubbleDelegate::ShouldCloseOnDeactivate() const {
+  return false;
+}
+
 bool DevModeBubbleDelegate::ShouldShowExtensionList() const {
   return false;
 }
@@ -138,21 +109,9 @@
   return g_shown_for_profiles.Pointer();
 }
 
-}  // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// DevModeBubbleController
-
 // static
-void DevModeBubbleController::ClearProfileListForTesting() {
+void DevModeBubbleDelegate::ClearProfileListForTesting() {
   g_shown_for_profiles.Get().clear();
 }
 
-DevModeBubbleController::DevModeBubbleController(Browser* browser)
-    : ExtensionMessageBubbleController(
-          new DevModeBubbleDelegate(browser->profile()), browser) {}
-
-DevModeBubbleController::~DevModeBubbleController() {
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/dev_mode_bubble_delegate.h b/chrome/browser/extensions/dev_mode_bubble_delegate.h
new file mode 100644
index 0000000..b8bdaab
--- /dev/null
+++ b/chrome/browser/extensions/dev_mode_bubble_delegate.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_DEV_MODE_BUBBLE_DELEGATE_H_
+#define CHROME_BROWSER_EXTENSIONS_DEV_MODE_BUBBLE_DELEGATE_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/extensions/extension_message_bubble_controller.h"
+
+namespace extensions {
+
+class Extension;
+
+class DevModeBubbleDelegate
+    : public ExtensionMessageBubbleController::Delegate {
+ public:
+  explicit DevModeBubbleDelegate(Profile* profile);
+  ~DevModeBubbleDelegate() override;
+
+  // ExtensionMessageBubbleController::Delegate methods.
+  bool ShouldIncludeExtension(const Extension* extension) override;
+  void AcknowledgeExtension(
+      const std::string& extension_id,
+      ExtensionMessageBubbleController::BubbleAction user_action) override;
+  void PerformAction(const ExtensionIdList& list) override;
+  base::string16 GetTitle() const override;
+  base::string16 GetMessageBody(bool anchored_to_browser_action,
+                                int extension_count) const override;
+  base::string16 GetOverflowText(
+      const base::string16& overflow_count) const override;
+  GURL GetLearnMoreUrl() const override;
+  base::string16 GetActionButtonLabel() const override;
+  base::string16 GetDismissButtonLabel() const override;
+  bool ShouldCloseOnDeactivate() const override;
+  bool ShouldShowExtensionList() const override;
+  bool ShouldHighlightExtensions() const override;
+  bool ShouldLimitToEnabledExtensions() const override;
+  void LogExtensionCount(size_t count) override;
+  void LogAction(ExtensionMessageBubbleController::BubbleAction) override;
+  std::set<Profile*>* GetProfileSet() override;
+
+  static void ClearProfileListForTesting();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DevModeBubbleDelegate);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_DEV_MODE_BUBBLE_DELEGATE_H_
diff --git a/chrome/browser/extensions/extension_install_prompt_unittest.cc b/chrome/browser/extensions/extension_install_prompt_unittest.cc
index 8102a1f..82c723f1 100644
--- a/chrome/browser/extensions/extension_install_prompt_unittest.cc
+++ b/chrome/browser/extensions/extension_install_prompt_unittest.cc
@@ -7,7 +7,9 @@
 #include "base/run_loop.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/extensions/extension_install_prompt_show_params.h"
+#include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_web_contents_factory.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/feature_switch.h"
@@ -21,6 +23,8 @@
 
 namespace extensions {
 
+namespace {
+
 void VerifyPromptPermissionsCallback(
     const base::Closure& quit_closure,
     size_t regular_permissions_count,
@@ -38,8 +42,31 @@
   quit_closure.Run();
 }
 
-TEST(ExtensionInstallPromptUnittest, PromptShowsPermissionWarnings) {
-  content::TestBrowserThreadBundle thread_bundle;
+class ExtensionInstallPromptUnitTest : public testing::Test {
+ public:
+  ExtensionInstallPromptUnitTest() {}
+  ~ExtensionInstallPromptUnitTest() override {}
+
+  // testing::Test:
+  void SetUp() override {
+    profile_.reset(new TestingProfile());
+  }
+  void TearDown() override {
+    profile_.reset();
+  }
+
+  Profile* profile() { return profile_.get(); }
+
+ private:
+  content::TestBrowserThreadBundle thread_bundle_;
+  scoped_ptr<TestingProfile> profile_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExtensionInstallPromptUnitTest);
+};
+
+}  // namespace
+
+TEST_F(ExtensionInstallPromptUnitTest, PromptShowsPermissionWarnings) {
   APIPermissionSet api_permissions;
   api_permissions.insert(APIPermission::kTab);
   scoped_ptr<const PermissionSet> permission_set(
@@ -51,7 +78,9 @@
                              .Set("version", "1.0")
                              .Set("manifest_version", 2)
                              .Set("description", "Random Ext")).Build();
-  ExtensionInstallPrompt prompt(nullptr /* no web contents in this test */);
+
+  content::TestWebContentsFactory factory;
+  ExtensionInstallPrompt prompt(factory.CreateWebContents(profile()));
   base::RunLoop run_loop;
   prompt.set_callback_for_test(
       base::Bind(&VerifyPromptPermissionsCallback,
@@ -63,9 +92,7 @@
   run_loop.Run();
 }
 
-TEST(ExtensionInstallPromptUnittest, PromptShowsWithheldPermissions) {
-  content::TestBrowserThreadBundle thread_bundle;
-
+TEST_F(ExtensionInstallPromptUnitTest, PromptShowsWithheldPermissions) {
   // Enable consent flag so that <all_hosts> permissions get withheld.
   FeatureSwitch::ScopedOverride enable_scripts_switch(
       FeatureSwitch::scripts_require_action(), true);
@@ -80,7 +107,9 @@
                                   ListBuilder().Append("http://*/*")
                                                .Append("http://www.google.com/")
                                                .Append("tabs"))).Build();
-  ExtensionInstallPrompt prompt(nullptr /* no web contents in this test */);
+
+  content::TestWebContentsFactory factory;
+  ExtensionInstallPrompt prompt(factory.CreateWebContents(profile()));
   base::RunLoop run_loop;
 
   // We expect <all_hosts> to be withheld, but http://www.google.com/ and tabs
@@ -95,8 +124,8 @@
   run_loop.Run();
 }
 
-TEST(ExtensionInstallPromptUnittest, DelegatedPromptShowsOptionalPermissions) {
-  content::TestBrowserThreadBundle thread_bundle;
+TEST_F(ExtensionInstallPromptUnitTest,
+       DelegatedPromptShowsOptionalPermissions) {
   scoped_refptr<const Extension> extension =
       ExtensionBuilder().SetManifest(
           DictionaryBuilder().Set("name", "foo")
@@ -107,7 +136,9 @@
                                   ListBuilder().Append("clipboardRead"))
                              .Set("optional_permissions",
                                   ListBuilder().Append("tabs"))).Build();
-  ExtensionInstallPrompt prompt(nullptr /* no web contents in this test */);
+
+  content::TestWebContentsFactory factory;
+  ExtensionInstallPrompt prompt(factory.CreateWebContents(profile()));
   base::RunLoop run_loop;
   prompt.set_callback_for_test(
       base::Bind(&VerifyPromptPermissionsCallback,
diff --git a/chrome/browser/extensions/extension_message_bubble_controller.cc b/chrome/browser/extensions/extension_message_bubble_controller.cc
index b9cc19c1..8dd0160 100644
--- a/chrome/browser/extensions/extension_message_bubble_controller.cc
+++ b/chrome/browser/extensions/extension_message_bubble_controller.cc
@@ -155,7 +155,9 @@
   return *GetOrCreateExtensionList();
 }
 
-bool ExtensionMessageBubbleController::CloseOnDeactivate() { return false; }
+bool ExtensionMessageBubbleController::CloseOnDeactivate() {
+  return delegate_->ShouldCloseOnDeactivate();
+}
 
 void ExtensionMessageBubbleController::HighlightExtensionsIfNecessary() {
   if (delegate_->ShouldHighlightExtensions() && !did_highlight_) {
diff --git a/chrome/browser/extensions/extension_message_bubble_controller.h b/chrome/browser/extensions/extension_message_bubble_controller.h
index 7bd311d..40e5b81be 100644
--- a/chrome/browser/extensions/extension_message_bubble_controller.h
+++ b/chrome/browser/extensions/extension_message_bubble_controller.h
@@ -57,6 +57,9 @@
     virtual base::string16 GetActionButtonLabel() const = 0;
     virtual base::string16 GetDismissButtonLabel() const = 0;
 
+    // Returns true if the bubble should close when the widget deactivates.
+    virtual bool ShouldCloseOnDeactivate() const = 0;
+
     // Whether to show a list of extensions in the bubble.
     virtual bool ShouldShowExtensionList() const = 0;
 
@@ -126,7 +129,7 @@
   const ExtensionIdList& GetExtensionIdList();
 
   // Whether to close the bubble when it loses focus.
-  virtual bool CloseOnDeactivate();
+  bool CloseOnDeactivate();
 
   // Highlights the affected extensions if appropriate. Safe to call multiple
   // times.
diff --git a/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc b/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
index 55a3675..129990f 100644
--- a/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
+++ b/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
@@ -7,13 +7,13 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "chrome/browser/extensions/dev_mode_bubble_controller.h"
+#include "chrome/browser/extensions/dev_mode_bubble_delegate.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/ntp_overridden_bubble_controller.h"
-#include "chrome/browser/extensions/proxy_overridden_bubble_controller.h"
-#include "chrome/browser/extensions/settings_api_bubble_controller.h"
-#include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
+#include "chrome/browser/extensions/ntp_overridden_bubble_delegate.h"
+#include "chrome/browser/extensions/proxy_overridden_bubble_delegate.h"
+#include "chrome/browser/extensions/settings_api_bubble_delegate.h"
+#include "chrome/browser/extensions/suspicious_extension_bubble_delegate.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_profile.h"
@@ -42,157 +42,43 @@
 
 namespace extensions {
 
-class TestDelegate {
+class TestExtensionMessageBubbleController :
+    public ExtensionMessageBubbleController {
  public:
-  TestDelegate()
-      : action_button_callback_count_(0),
+  TestExtensionMessageBubbleController(
+      ExtensionMessageBubbleController::Delegate* delegate,
+      Browser* browser)
+      : ExtensionMessageBubbleController(delegate, browser),
+        action_button_callback_count_(0),
         dismiss_button_callback_count_(0),
-        link_click_callback_count_(0) {
+        link_click_callback_count_(0) {}
+  ~TestExtensionMessageBubbleController() override {}
+
+  // ExtensionMessageBubbleController:
+  void OnBubbleAction() override {
+    ++action_button_callback_count_;
+    ExtensionMessageBubbleController::OnBubbleAction();
+  }
+  void OnBubbleDismiss() override {
+    ++dismiss_button_callback_count_;
+    ExtensionMessageBubbleController::OnBubbleDismiss();
+  }
+  void OnLinkClicked() override {
+    ++link_click_callback_count_;
+    ExtensionMessageBubbleController::OnLinkClicked();
   }
 
-  // Returns how often the dismiss button has been called.
-  size_t action_click_count() {
-    return action_button_callback_count_;
-  }
+  size_t action_click_count() { return action_button_callback_count_; }
+  size_t dismiss_click_count() { return dismiss_button_callback_count_; }
+  size_t link_click_count() { return link_click_callback_count_; }
 
-  // Returns how often the dismiss button has been called.
-  size_t dismiss_click_count() {
-    return dismiss_button_callback_count_;
-  }
-
-  // Returns how often the link has been clicked.
-  size_t link_click_count() {
-    return link_click_callback_count_;
-  }
-
- protected:
+ private:
+  // How often each button has been called.
   size_t action_button_callback_count_;
   size_t dismiss_button_callback_count_;
   size_t link_click_callback_count_;
-};
 
-// A test class for the SuspiciousExtensionBubbleController.
-class TestSuspiciousExtensionBubbleController
-    : public SuspiciousExtensionBubbleController,
-      public TestDelegate {
- public:
-  explicit TestSuspiciousExtensionBubbleController(Browser* browser)
-      : SuspiciousExtensionBubbleController(browser) {
-  }
-
-  void OnBubbleAction() override {
-    ++action_button_callback_count_;
-    SuspiciousExtensionBubbleController::OnBubbleAction();
-  }
-
-  void OnBubbleDismiss() override {
-    ++dismiss_button_callback_count_;
-    SuspiciousExtensionBubbleController::OnBubbleDismiss();
-  }
-
-  void OnLinkClicked() override {
-    ++link_click_callback_count_;
-    SuspiciousExtensionBubbleController::OnLinkClicked();
-  }
-};
-
-// A test class for the DevModeBubbleController.
-class TestDevModeBubbleController
-    : public DevModeBubbleController,
-      public TestDelegate {
- public:
-  explicit TestDevModeBubbleController(Browser* browser)
-      : DevModeBubbleController(browser) {
-  }
-
-  void OnBubbleAction() override {
-    ++action_button_callback_count_;
-    DevModeBubbleController::OnBubbleAction();
-  }
-
-  void OnBubbleDismiss() override {
-    ++dismiss_button_callback_count_;
-    DevModeBubbleController::OnBubbleDismiss();
-  }
-
-  void OnLinkClicked() override {
-    ++link_click_callback_count_;
-    DevModeBubbleController::OnLinkClicked();
-  }
-};
-
-// A test class for the SettingsApiBubbleController.
-class TestSettingsApiBubbleController : public SettingsApiBubbleController,
-                                        public TestDelegate {
- public:
-  TestSettingsApiBubbleController(Browser* browser,
-                                  SettingsApiOverrideType type)
-      : SettingsApiBubbleController(browser, type) {}
-
-  void OnBubbleAction() override {
-    ++action_button_callback_count_;
-    SettingsApiBubbleController::OnBubbleAction();
-  }
-
-  void OnBubbleDismiss() override {
-    ++dismiss_button_callback_count_;
-    SettingsApiBubbleController::OnBubbleDismiss();
-  }
-
-  void OnLinkClicked() override {
-    ++link_click_callback_count_;
-    SettingsApiBubbleController::OnLinkClicked();
-  }
-};
-
-// A test class for the NtpOverriddenBubbleController.
-class TestNtpOverriddenBubbleController
-    : public NtpOverriddenBubbleController,
-      public TestDelegate {
- public:
-  explicit TestNtpOverriddenBubbleController(Browser* browser)
-      : NtpOverriddenBubbleController(browser) {
-  }
-
-  void OnBubbleAction() override {
-    ++action_button_callback_count_;
-    NtpOverriddenBubbleController::OnBubbleAction();
-  }
-
-  void OnBubbleDismiss() override {
-    ++dismiss_button_callback_count_;
-    NtpOverriddenBubbleController::OnBubbleDismiss();
-  }
-
-  void OnLinkClicked() override {
-    ++link_click_callback_count_;
-    NtpOverriddenBubbleController::OnLinkClicked();
-  }
-};
-
-// A test class for the ProxyOverriddenBubbleController.
-class TestProxyOverriddenBubbleController
-    : public ProxyOverriddenBubbleController,
-      public TestDelegate {
- public:
-  explicit TestProxyOverriddenBubbleController(Browser* browser)
-      : ProxyOverriddenBubbleController(browser) {
-  }
-
-  void OnBubbleAction() override {
-    ++action_button_callback_count_;
-    ProxyOverriddenBubbleController::OnBubbleAction();
-  }
-
-  void OnBubbleDismiss() override {
-    ++dismiss_button_callback_count_;
-    ProxyOverriddenBubbleController::OnBubbleDismiss();
-  }
-
-  void OnLinkClicked() override {
-    ++link_click_callback_count_;
-    ProxyOverriddenBubbleController::OnLinkClicked();
-  }
+  DISALLOW_COPY_AND_ASSIGN(TestExtensionMessageBubbleController);
 };
 
 // A fake bubble used for testing the controller. Takes an action that specifies
@@ -429,8 +315,10 @@
   ASSERT_TRUE(LoadGenericExtension("2", kId2, Manifest::UNPACKED));
   ASSERT_TRUE(LoadGenericExtension("3", kId3, Manifest::EXTERNAL_POLICY));
 
-  scoped_ptr<TestSuspiciousExtensionBubbleController> controller(
-      new TestSuspiciousExtensionBubbleController(browser()));
+  scoped_ptr<TestExtensionMessageBubbleController> controller(
+      new TestExtensionMessageBubbleController(
+          new SuspiciousExtensionBubbleDelegate(browser()->profile()),
+          browser()));
   FakeExtensionMessageBubble bubble;
   bubble.set_action_on_show(
       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_DISMISS_BUTTON);
@@ -451,9 +339,11 @@
 
   EXPECT_FALSE(controller->delegate()->HasBubbleInfoBeenAcknowledged(kId1));
   EXPECT_FALSE(controller->delegate()->HasBubbleInfoBeenAcknowledged(kId2));
-  controller.reset(new TestSuspiciousExtensionBubbleController(
-      browser()));
-  SuspiciousExtensionBubbleController::ClearProfileListForTesting();
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new SuspiciousExtensionBubbleDelegate(browser()->profile()),
+          browser()));
+  SuspiciousExtensionBubbleDelegate::ClearProfileListForTesting();
   EXPECT_TRUE(controller->ShouldShow());
   suspicious_extensions = controller->GetExtensionList();
   ASSERT_EQ(1U, suspicious_extensions.size());
@@ -474,9 +364,11 @@
 
   bubble.set_action_on_show(
       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
-  controller.reset(new TestSuspiciousExtensionBubbleController(
-      browser()));
-  SuspiciousExtensionBubbleController::ClearProfileListForTesting();
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new SuspiciousExtensionBubbleDelegate(browser()->profile()),
+          browser()));
+  SuspiciousExtensionBubbleDelegate::ClearProfileListForTesting();
   EXPECT_TRUE(controller->ShouldShow());
   suspicious_extensions = controller->GetExtensionList();
   ASSERT_EQ(2U, suspicious_extensions.size());
@@ -502,8 +394,10 @@
   ASSERT_TRUE(LoadGenericExtension("2", kId2, Manifest::UNPACKED));
   ASSERT_TRUE(LoadGenericExtension("3", kId3, Manifest::EXTERNAL_POLICY));
 
-  scoped_ptr<TestDevModeBubbleController> controller(
-      new TestDevModeBubbleController(browser()));
+  scoped_ptr<TestExtensionMessageBubbleController> controller(
+      new TestExtensionMessageBubbleController(
+          new DevModeBubbleDelegate(browser()->profile()),
+          browser()));
 
   // The list will contain one enabled unpacked extension.
   EXPECT_TRUE(controller->ShouldShow());
@@ -532,9 +426,11 @@
   // Do it again, but now press different button (Disable).
   bubble.set_action_on_show(
       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON);
-  controller.reset(new TestDevModeBubbleController(
-      browser()));
-  DevModeBubbleController::ClearProfileListForTesting();
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new DevModeBubbleDelegate(browser()->profile()),
+          browser()));
+  DevModeBubbleDelegate::ClearProfileListForTesting();
   EXPECT_TRUE(controller->ShouldShow());
   dev_mode_extensions = controller->GetExtensionList();
   EXPECT_EQ(2U, dev_mode_extensions.size());
@@ -553,9 +449,11 @@
   // Show the dialog a third time, but now press the learn more link.
   bubble.set_action_on_show(
       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
-  controller.reset(new TestDevModeBubbleController(
-      browser()));
-  DevModeBubbleController::ClearProfileListForTesting();
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new DevModeBubbleDelegate(browser()->profile()),
+          browser()));
+  DevModeBubbleDelegate::ClearProfileListForTesting();
   EXPECT_TRUE(controller->ShouldShow());
   dev_mode_extensions = controller->GetExtensionList();
   EXPECT_EQ(2U, dev_mode_extensions.size());
@@ -571,9 +469,11 @@
   service_->DisableExtension(kId1, Extension::DISABLE_USER_ACTION);
   service_->DisableExtension(kId2, Extension::DISABLE_USER_ACTION);
 
-  controller.reset(new TestDevModeBubbleController(
-      browser()));
-  DevModeBubbleController::ClearProfileListForTesting();
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new DevModeBubbleDelegate(browser()->profile()),
+          browser()));
+  DevModeBubbleDelegate::ClearProfileListForTesting();
   EXPECT_FALSE(controller->ShouldShow());
   dev_mode_extensions = controller->GetExtensionList();
   EXPECT_EQ(0U, dev_mode_extensions.size());
@@ -622,9 +522,11 @@
         break;
     }
 
-    scoped_ptr<TestSettingsApiBubbleController> controller(
-        new TestSettingsApiBubbleController(
-            browser(), static_cast<SettingsApiOverrideType>(i)));
+    SettingsApiOverrideType type = static_cast<SettingsApiOverrideType>(i);
+    scoped_ptr<TestExtensionMessageBubbleController> controller(
+        new TestExtensionMessageBubbleController(
+            new SettingsApiBubbleDelegate(browser()->profile(), type),
+            browser()));
 
     // The list will contain one enabled unpacked extension (ext 2).
     EXPECT_TRUE(controller->ShouldShow());
@@ -661,8 +563,10 @@
     // Simulate clicking the learn more link to dismiss it.
     bubble.set_action_on_show(
         FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
-    controller.reset(new TestSettingsApiBubbleController(
-        browser(), static_cast<SettingsApiOverrideType>(i)));
+    controller.reset(
+        new TestExtensionMessageBubbleController(
+            new SettingsApiBubbleDelegate(browser()->profile(), type),
+            browser()));
     bubble.set_controller(controller.get());
     bubble.Show();
     EXPECT_EQ(1U, controller->link_click_count());
@@ -682,8 +586,10 @@
     // Do it again, but now opt to disable the extension.
     bubble.set_action_on_show(
         FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON);
-    controller.reset(new TestSettingsApiBubbleController(
-        browser(), static_cast<SettingsApiOverrideType>(i)));
+    controller.reset(
+        new TestExtensionMessageBubbleController(
+            new SettingsApiBubbleDelegate(browser()->profile(), type),
+            browser()));
     EXPECT_TRUE(controller->ShouldShow());
     override_extensions = controller->GetExtensionList();
     EXPECT_EQ(1U, override_extensions.size());
@@ -728,8 +634,10 @@
   ASSERT_TRUE(LoadExtensionOverridingNtp("2", kId2, Manifest::UNPACKED));
   ASSERT_TRUE(LoadExtensionOverridingStart("3", kId3, Manifest::UNPACKED));
 
-  scoped_ptr<TestNtpOverriddenBubbleController> controller(
-      new TestNtpOverriddenBubbleController(browser()));
+  scoped_ptr<TestExtensionMessageBubbleController> controller(
+      new TestExtensionMessageBubbleController(
+          new NtpOverriddenBubbleDelegate(browser()->profile()),
+          browser()));
 
   // The list will contain one enabled unpacked extension (ext 2).
   EXPECT_TRUE(controller->ShouldShow());
@@ -767,7 +675,10 @@
   // Simulate clicking the learn more link to dismiss it.
   bubble.set_action_on_show(
       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
-  controller.reset(new TestNtpOverriddenBubbleController(browser()));
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new NtpOverriddenBubbleDelegate(browser()->profile()),
+          browser()));
   EXPECT_TRUE(controller->ShouldShow());
   bubble.set_controller(controller.get());
   bubble.Show();
@@ -788,7 +699,10 @@
   // Do it again, but now opt to disable the extension.
   bubble.set_action_on_show(
       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON);
-  controller.reset(new TestNtpOverriddenBubbleController(browser()));
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new NtpOverriddenBubbleDelegate(browser()->profile()),
+          browser()));
   EXPECT_TRUE(controller->ShouldShow());
   override_extensions = controller->GetExtensionList();
   EXPECT_EQ(1U, override_extensions.size());
@@ -856,8 +770,10 @@
   SetInstallTime(kId2, base::Time::Now(), prefs);
   SetInstallTime(kId3, old_enough, prefs);
 
-  scoped_ptr<TestProxyOverriddenBubbleController> controller(
-      new TestProxyOverriddenBubbleController(browser()));
+  scoped_ptr<TestExtensionMessageBubbleController> controller(
+      new TestExtensionMessageBubbleController(
+          new ProxyOverriddenBubbleDelegate(browser()->profile()),
+          browser()));
 
   // The second extension is too new to warn about.
   EXPECT_FALSE(controller->ShouldShow());
@@ -900,7 +816,10 @@
   // Simulate clicking the learn more link to dismiss it.
   bubble.set_action_on_show(
       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_LINK);
-  controller.reset(new TestProxyOverriddenBubbleController(browser()));
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new ProxyOverriddenBubbleDelegate(browser()->profile()),
+          browser()));
   EXPECT_TRUE(controller->ShouldShow());
   bubble.set_controller(controller.get());
   bubble.Show();
@@ -921,7 +840,10 @@
   // Do it again, but now opt to disable the extension.
   bubble.set_action_on_show(
       FakeExtensionMessageBubble::BUBBLE_ACTION_CLICK_ACTION_BUTTON);
-  controller.reset(new TestProxyOverriddenBubbleController(browser()));
+  controller.reset(
+      new TestExtensionMessageBubbleController(
+          new ProxyOverriddenBubbleDelegate(browser()->profile()),
+          browser()));
   EXPECT_TRUE(controller->ShouldShow());
   override_extensions = controller->GetExtensionList();
   EXPECT_EQ(1U, override_extensions.size());
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 7390a263..c7d347ba 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -60,6 +60,7 @@
 #include "chrome/common/url_constants.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/crx_file/id_util.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
diff --git a/chrome/browser/extensions/extension_service_sync_unittest.cc b/chrome/browser/extensions/extension_service_sync_unittest.cc
index c026d79..cbf5c1e 100644
--- a/chrome/browser/extensions/extension_service_sync_unittest.cc
+++ b/chrome/browser/extensions/extension_service_sync_unittest.cc
@@ -24,6 +24,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/sync_helper.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/crx_file/id_util.h"
 #include "extensions/browser/app_sorting.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
@@ -31,8 +32,10 @@
 #include "extensions/browser/management_policy.h"
 #include "extensions/browser/test_management_policy.h"
 #include "extensions/common/constants.h"
+#include "extensions/common/extension_builder.h"
 #include "extensions/common/manifest_url_handlers.h"
 #include "extensions/common/permissions/permission_set.h"
+#include "extensions/common/value_builder.h"
 #include "sync/api/fake_sync_change_processor.h"
 #include "sync/api/sync_data.h"
 #include "sync/api/sync_error_factory_mock.h"
@@ -1716,4 +1719,52 @@
       registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1]));
 }
 
+TEST_F(ExtensionServiceSyncTest, SyncExtensionHasAllhostsWithheld) {
+  InitializeEmptyExtensionService();
+
+  // Create an extension that needs all-hosts.
+  const std::string kName("extension");
+  scoped_refptr<const Extension> extension =
+      extensions::ExtensionBuilder()
+      .SetLocation(Manifest::INTERNAL)
+      .SetManifest(
+          extensions::DictionaryBuilder()
+              .Set("name", kName)
+              .Set("description", "foo")
+              .Set("manifest_version", 2)
+              .Set("version", "1.0")
+              .Set("permissions", extensions::ListBuilder().Append("*://*/*")))
+      .SetID(crx_file::id_util::GenerateId(kName))
+      .Build();
+
+  // Install and enable it.
+  service()->AddExtension(extension.get());
+  service()->GrantPermissionsAndEnableExtension(extension.get());
+  const std::string id = extension->id();
+  EXPECT_TRUE(registry()->enabled_extensions().GetByID(id));
+
+  // Simulate a sync node coming in where the extension had all-hosts withheld.
+  // This means that it should have all-hosts withheld on this machine, too.
+  syncer::SyncChangeList change_list;
+  sync_pb::EntitySpecifics specifics;
+  sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
+  ext_specifics->set_id(id);
+  ext_specifics->set_name(kName);
+  ext_specifics->set_version("1.0");
+  ext_specifics->set_all_urls_enabled(false);
+  ext_specifics->set_enabled(true);
+  syncer::SyncData sync_data =
+      syncer::SyncData::CreateLocalData(id, "Name", specifics);
+  change_list.push_back(syncer::SyncChange(FROM_HERE,
+                                           syncer::SyncChange::ACTION_UPDATE,
+                                           sync_data));
+
+  extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
+
+  EXPECT_TRUE(registry()->enabled_extensions().GetByID(id));
+  EXPECT_FALSE(extensions::util::AllowedScriptingOnAllUrls(id, profile()));
+  EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(id, profile()));
+  EXPECT_FALSE(extensions::util::AllowedScriptingOnAllUrls(id, profile()));
+}
+
 #endif  // defined(ENABLE_SUPERVISED_USERS)
diff --git a/chrome/browser/extensions/extension_util.cc b/chrome/browser/extensions/extension_util.cc
index 9696561..639d7a4 100644
--- a/chrome/browser/extensions/extension_util.cc
+++ b/chrome/browser/extensions/extension_util.cc
@@ -238,11 +238,11 @@
                                   content::BrowserContext* context,
                                   bool allowed) {
   if (allowed != AllowedScriptingOnAllUrls(extension_id, context)) {
-    SetAllowedScriptingOnAllUrlsHelper(context, extension_id, allowed, true);
     ExtensionPrefs::Get(context)->UpdateExtensionPref(
         extension_id,
         kHasSetScriptOnAllUrlsPrefName,
         new base::FundamentalValue(true));
+    SetAllowedScriptingOnAllUrlsHelper(context, extension_id, allowed, true);
   }
 }
 
diff --git a/chrome/browser/extensions/fake_safe_browsing_database_manager.cc b/chrome/browser/extensions/fake_safe_browsing_database_manager.cc
index 0897401..3dc42740 100644
--- a/chrome/browser/extensions/fake_safe_browsing_database_manager.cc
+++ b/chrome/browser/extensions/fake_safe_browsing_database_manager.cc
@@ -100,14 +100,14 @@
   std::vector<SBFullHash> extension_id_hashes;
   std::transform(extension_ids_vector.begin(), extension_ids_vector.end(),
                  std::back_inserter(extension_id_hashes),
-                 safe_browsing_util::StringToSBFullHash);
+                 safe_browsing::StringToSBFullHash);
 
   scoped_ptr<SafeBrowsingCheck> safe_browsing_check(
       new SafeBrowsingCheck(
           std::vector<GURL>(),
           extension_id_hashes,
           client,
-          safe_browsing_util::EXTENSIONBLACKLIST,
+          safe_browsing::EXTENSIONBLACKLIST,
           std::vector<SBThreatType>(1, SB_THREAT_TYPE_EXTENSION)));
 
   for (size_t i = 0; i < extension_ids_vector.size(); ++i) {
diff --git a/chrome/browser/extensions/ntp_overridden_bubble_controller.h b/chrome/browser/extensions/ntp_overridden_bubble_controller.h
deleted file mode 100644
index d5d84b0..0000000
--- a/chrome/browser/extensions/ntp_overridden_bubble_controller.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_NTP_OVERRIDDEN_BUBBLE_CONTROLLER_H_
-#define CHROME_BROWSER_EXTENSIONS_NTP_OVERRIDDEN_BUBBLE_CONTROLLER_H_
-
-#include <string>
-#include "chrome/browser/extensions/extension_message_bubble_controller.h"
-
-namespace extensions {
-
-class NtpOverriddenBubbleController : public ExtensionMessageBubbleController {
- public:
-  explicit NtpOverriddenBubbleController(Browser* browser);
-  ~NtpOverriddenBubbleController() override;
-
-  // ExtensionMessageBubbleController:
-  bool CloseOnDeactivate() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NtpOverriddenBubbleController);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_NTP_OVERRIDDEN_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/extensions/ntp_overridden_bubble_controller.cc b/chrome/browser/extensions/ntp_overridden_bubble_delegate.cc
similarity index 64%
rename from chrome/browser/extensions/ntp_overridden_bubble_controller.cc
rename to chrome/browser/extensions/ntp_overridden_bubble_delegate.cc
index c46e67c..f76ebdc8 100644
--- a/chrome/browser/extensions/ntp_overridden_bubble_controller.cc
+++ b/chrome/browser/extensions/ntp_overridden_bubble_delegate.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/extensions/ntp_overridden_bubble_controller.h"
+#include "chrome/browser/extensions/ntp_overridden_bubble_delegate.h"
 
 #include "base/metrics/histogram.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -16,52 +16,15 @@
 #include "grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
-using extensions::ExtensionMessageBubbleController;
-using extensions::NtpOverriddenBubbleController;
-
 namespace {
 
 // Whether the user has been notified about extension overriding the new tab
 // page.
 const char kNtpBubbleAcknowledged[] = "ack_ntp_bubble";
 
-////////////////////////////////////////////////////////////////////////////////
-// NtpOverriddenBubbleDelegate
+}  // namespace
 
-class NtpOverriddenBubbleDelegate
-    : public extensions::ExtensionMessageBubbleController::Delegate {
- public:
-  explicit NtpOverriddenBubbleDelegate(Profile* profile);
-  ~NtpOverriddenBubbleDelegate() override;
-
-  // ExtensionMessageBubbleController::Delegate methods.
-  bool ShouldIncludeExtension(const extensions::Extension* extension) override;
-  void AcknowledgeExtension(
-      const std::string& extension_id,
-      extensions::ExtensionMessageBubbleController::BubbleAction user_action)
-      override;
-  void PerformAction(const extensions::ExtensionIdList& list) override;
-  base::string16 GetTitle() const override;
-  base::string16 GetMessageBody(bool anchored_to_browser_action,
-                                int extension_count) const override;
-  base::string16 GetOverflowText(
-      const base::string16& overflow_count) const override;
-  GURL GetLearnMoreUrl() const override;
-  base::string16 GetActionButtonLabel() const override;
-  base::string16 GetDismissButtonLabel() const override;
-  bool ShouldShowExtensionList() const override;
-  bool ShouldHighlightExtensions() const override;
-  bool ShouldLimitToEnabledExtensions() const override;
-  void LogExtensionCount(size_t count) override;
-  void LogAction(extensions::ExtensionMessageBubbleController::BubbleAction
-                     action) override;
-
- private:
-  // The ID of the extension we are showing the bubble for.
-  std::string extension_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(NtpOverriddenBubbleDelegate);
-};
+namespace extensions {
 
 NtpOverriddenBubbleDelegate::NtpOverriddenBubbleDelegate(
     Profile* profile)
@@ -139,6 +102,10 @@
   return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
 }
 
+bool NtpOverriddenBubbleDelegate::ShouldCloseOnDeactivate() const {
+  return true;
+}
+
 bool NtpOverriddenBubbleDelegate::ShouldShowExtensionList() const {
   return false;
 }
@@ -162,22 +129,4 @@
       ExtensionMessageBubbleController::ACTION_BOUNDARY);
 }
 
-}  // namespace
-
-namespace extensions {
-
-////////////////////////////////////////////////////////////////////////////////
-// NtpOverriddenBubbleController
-
-NtpOverriddenBubbleController::NtpOverriddenBubbleController(Browser* browser)
-    : ExtensionMessageBubbleController(
-          new NtpOverriddenBubbleDelegate(browser->profile()),
-          browser) {}
-
-NtpOverriddenBubbleController::~NtpOverriddenBubbleController() {}
-
-bool NtpOverriddenBubbleController::CloseOnDeactivate() {
-  return true;
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/ntp_overridden_bubble_delegate.h b/chrome/browser/extensions/ntp_overridden_bubble_delegate.h
new file mode 100644
index 0000000..80026ab
--- /dev/null
+++ b/chrome/browser/extensions/ntp_overridden_bubble_delegate.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_NTP_OVERRIDDEN_BUBBLE_DELEGATE_H_
+#define CHROME_BROWSER_EXTENSIONS_NTP_OVERRIDDEN_BUBBLE_DELEGATE_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/extensions/extension_message_bubble_controller.h"
+
+namespace extensions {
+
+class NtpOverriddenBubbleDelegate
+    : public ExtensionMessageBubbleController::Delegate {
+ public:
+  explicit NtpOverriddenBubbleDelegate(Profile* profile);
+  ~NtpOverriddenBubbleDelegate() override;
+
+  // ExtensionMessageBubbleController::Delegate methods.
+  bool ShouldIncludeExtension(const extensions::Extension* extension) override;
+  void AcknowledgeExtension(
+      const std::string& extension_id,
+      extensions::ExtensionMessageBubbleController::BubbleAction user_action)
+      override;
+  void PerformAction(const extensions::ExtensionIdList& list) override;
+  base::string16 GetTitle() const override;
+  base::string16 GetMessageBody(bool anchored_to_browser_action,
+                                int extension_count) const override;
+  base::string16 GetOverflowText(
+      const base::string16& overflow_count) const override;
+  GURL GetLearnMoreUrl() const override;
+  base::string16 GetActionButtonLabel() const override;
+  base::string16 GetDismissButtonLabel() const override;
+  bool ShouldCloseOnDeactivate() const override;
+  bool ShouldShowExtensionList() const override;
+  bool ShouldHighlightExtensions() const override;
+  bool ShouldLimitToEnabledExtensions() const override;
+  void LogExtensionCount(size_t count) override;
+  void LogAction(ExtensionMessageBubbleController::BubbleAction) override;
+
+ private:
+  // The ID of the extension we are showing the bubble for.
+  std::string extension_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(NtpOverriddenBubbleDelegate);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_NTP_OVERRIDDEN_BUBBLE_DELEGATE_H_
diff --git a/chrome/browser/extensions/permissions_updater.cc b/chrome/browser/extensions/permissions_updater.cc
index 3883130f..dbec44b2 100644
--- a/chrome/browser/extensions/permissions_updater.cc
+++ b/chrome/browser/extensions/permissions_updater.cc
@@ -159,7 +159,7 @@
   scoped_ptr<const PermissionSet> granted;
   scoped_ptr<const PermissionSet> withheld;
   ScriptingPermissionsModifier(browser_context_, make_scoped_refptr(extension))
-      .WithholdPermissions(required, &granted, &withheld, false);
+      .WithholdPermissions(required, &granted, &withheld, true);
   return PermissionSet::CreateDifference(
       extension->permissions_data()->active_permissions(), *granted);
 }
@@ -193,7 +193,7 @@
   ScriptingPermissionsModifier(browser_context_, make_scoped_refptr(extension))
       .WithholdPermissions(*bounded_active, &granted_permissions,
                            &withheld_permissions,
-                           (init_flag_ & INIT_FLAG_TRANSIENT) == 0);
+                           (init_flag_ & INIT_FLAG_TRANSIENT) != 0);
 
   SetPermissions(extension, granted_permissions.Pass(),
                  withheld_permissions.Pass());
diff --git a/chrome/browser/extensions/proxy_overridden_bubble_controller.h b/chrome/browser/extensions/proxy_overridden_bubble_controller.h
deleted file mode 100644
index d5d46b8..0000000
--- a/chrome/browser/extensions/proxy_overridden_bubble_controller.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_PROXY_OVERRIDDEN_BUBBLE_CONTROLLER_H_
-#define CHROME_BROWSER_EXTENSIONS_PROXY_OVERRIDDEN_BUBBLE_CONTROLLER_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "chrome/browser/extensions/extension_message_bubble_controller.h"
-
-class Browser;
-
-namespace extensions {
-
-class ProxyOverriddenBubbleController
-    : public ExtensionMessageBubbleController {
- public:
-  explicit ProxyOverriddenBubbleController(Browser* browser);
-  ~ProxyOverriddenBubbleController() override;
-
-  // ExtensionMessageBubbleController:
-  bool CloseOnDeactivate() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ProxyOverriddenBubbleController);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_PROXY_OVERRIDDEN_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/extensions/proxy_overridden_bubble_controller.cc b/chrome/browser/extensions/proxy_overridden_bubble_delegate.cc
similarity index 70%
rename from chrome/browser/extensions/proxy_overridden_bubble_controller.cc
rename to chrome/browser/extensions/proxy_overridden_bubble_delegate.cc
index fa66901f..59c7dd43 100644
--- a/chrome/browser/extensions/proxy_overridden_bubble_controller.cc
+++ b/chrome/browser/extensions/proxy_overridden_bubble_delegate.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/extensions/proxy_overridden_bubble_controller.h"
+#include "chrome/browser/extensions/proxy_overridden_bubble_delegate.h"
 
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
@@ -29,42 +29,7 @@
 // Whether the user has been notified about extension overriding the proxy.
 const char kProxyBubbleAcknowledged[] = "ack_proxy_bubble";
 
-////////////////////////////////////////////////////////////////////////////////
-// ProxyOverriddenBubbleDelegate
-
-class ProxyOverriddenBubbleDelegate
-    : public ExtensionMessageBubbleController::Delegate {
- public:
-  explicit ProxyOverriddenBubbleDelegate(Profile* profile);
-  ~ProxyOverriddenBubbleDelegate() override;
-
-  // ExtensionMessageBubbleController::Delegate methods.
-  bool ShouldIncludeExtension(const Extension* extension) override;
-  void AcknowledgeExtension(
-      const std::string& extension_id,
-      ExtensionMessageBubbleController::BubbleAction user_action) override;
-  void PerformAction(const ExtensionIdList& list) override;
-  base::string16 GetTitle() const override;
-  base::string16 GetMessageBody(bool anchored_to_browser_action,
-                                int extension_count) const override;
-  base::string16 GetOverflowText(
-      const base::string16& overflow_count) const override;
-  GURL GetLearnMoreUrl() const override;
-  base::string16 GetActionButtonLabel() const override;
-  base::string16 GetDismissButtonLabel() const override;
-  bool ShouldShowExtensionList() const override;
-  bool ShouldHighlightExtensions() const override;
-  bool ShouldLimitToEnabledExtensions() const override;
-  void LogExtensionCount(size_t count) override;
-  void LogAction(
-      ExtensionMessageBubbleController::BubbleAction action) override;
-
- private:
-  // The ID of the extension we are showing the bubble for.
-  std::string extension_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProxyOverriddenBubbleDelegate);
-};
+}  // namespace
 
 ProxyOverriddenBubbleDelegate::ProxyOverriddenBubbleDelegate(
     Profile* profile)
@@ -151,6 +116,10 @@
   return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
 }
 
+bool ProxyOverriddenBubbleDelegate::ShouldCloseOnDeactivate() const {
+  return false;
+}
+
 bool ProxyOverriddenBubbleDelegate::ShouldShowExtensionList() const {
   return false;
 }
@@ -174,21 +143,4 @@
                             ExtensionMessageBubbleController::ACTION_BOUNDARY);
 }
 
-}  // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// ProxyOverriddenBubbleController
-
-ProxyOverriddenBubbleController::ProxyOverriddenBubbleController(
-    Browser* browser)
-    : ExtensionMessageBubbleController(
-          new ProxyOverriddenBubbleDelegate(browser->profile()),
-          browser) {}
-
-ProxyOverriddenBubbleController::~ProxyOverriddenBubbleController() {}
-
-bool ProxyOverriddenBubbleController::CloseOnDeactivate() {
-  return false;
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/proxy_overridden_bubble_delegate.h b/chrome/browser/extensions/proxy_overridden_bubble_delegate.h
new file mode 100644
index 0000000..cbd851d1
--- /dev/null
+++ b/chrome/browser/extensions/proxy_overridden_bubble_delegate.h
@@ -0,0 +1,53 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_PROXY_OVERRIDDEN_BUBBLE_DELEGATE_H_
+#define CHROME_BROWSER_EXTENSIONS_PROXY_OVERRIDDEN_BUBBLE_DELEGATE_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/extensions/extension_message_bubble_controller.h"
+
+class Browser;
+
+namespace extensions {
+
+class ProxyOverriddenBubbleDelegate
+    : public ExtensionMessageBubbleController::Delegate {
+ public:
+  explicit ProxyOverriddenBubbleDelegate(Profile* profile);
+  ~ProxyOverriddenBubbleDelegate() override;
+
+  // ExtensionMessageBubbleController::Delegate methods.
+  bool ShouldIncludeExtension(const Extension* extension) override;
+  void AcknowledgeExtension(
+      const std::string& extension_id,
+      ExtensionMessageBubbleController::BubbleAction user_action) override;
+  void PerformAction(const ExtensionIdList& list) override;
+  base::string16 GetTitle() const override;
+  base::string16 GetMessageBody(bool anchored_to_browser_action,
+                                int extension_count) const override;
+  base::string16 GetOverflowText(
+      const base::string16& overflow_count) const override;
+  GURL GetLearnMoreUrl() const override;
+  base::string16 GetActionButtonLabel() const override;
+  base::string16 GetDismissButtonLabel() const override;
+  bool ShouldCloseOnDeactivate() const override;
+  bool ShouldShowExtensionList() const override;
+  bool ShouldHighlightExtensions() const override;
+  bool ShouldLimitToEnabledExtensions() const override;
+  void LogExtensionCount(size_t count) override;
+  void LogAction(ExtensionMessageBubbleController::BubbleAction) override;
+
+ private:
+  // The ID of the extension we are showing the bubble for.
+  std::string extension_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyOverriddenBubbleDelegate);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_PROXY_OVERRIDDEN_BUBBLE_DELEGATE_H_
diff --git a/chrome/browser/extensions/scripting_permissions_modifier.cc b/chrome/browser/extensions/scripting_permissions_modifier.cc
index eaaa9b68..71e3c82b 100644
--- a/chrome/browser/extensions/scripting_permissions_modifier.cc
+++ b/chrome/browser/extensions/scripting_permissions_modifier.cc
@@ -90,7 +90,7 @@
   scoped_ptr<const PermissionSet> granted_permissions;
   scoped_ptr<const PermissionSet> withheld_permissions;
   WithholdPermissions(required_permissions, &granted_permissions,
-                      &withheld_permissions, false);
+                      &withheld_permissions, true);
   if (!granted_permissions->effective_hosts().MatchesURL(origin) &&
       withheld_permissions->effective_hosts().MatchesURL(origin))
     return true;
@@ -124,13 +124,23 @@
     const PermissionSet& permissions,
     scoped_ptr<const PermissionSet>* granted_permissions_out,
     scoped_ptr<const PermissionSet>* withheld_permissions_out,
-    bool check_prefs) const {
+    bool use_initial_state) const {
   bool should_withhold = false;
-  if (CanAffectExtension(permissions))
-    should_withhold = check_prefs
-                          ? !util::AllowedScriptingOnAllUrls(extension_->id(),
-                                                             browser_context_)
-                          : !util::DefaultAllowedScriptingOnAllUrls();
+  if (CanAffectExtension(permissions)) {
+    if (use_initial_state) {
+      // If the user ever set the extension's "all-urls" preference, then the
+      // initial state was withheld. This is important, since the all-urls
+      // permission should be shown as revokable. Otherwise, default to whatever
+      // the system setting is.
+      should_withhold =
+          util::HasSetAllowedScriptingOnAllUrls(extension_->id(),
+                                                browser_context_) ||
+          !util::DefaultAllowedScriptingOnAllUrls();
+    } else {
+      should_withhold =
+          !util::AllowedScriptingOnAllUrls(extension_->id(), browser_context_);
+    }
+  }
 
   if (!should_withhold) {
     *granted_permissions_out = permissions.Clone();
diff --git a/chrome/browser/extensions/scripting_permissions_modifier.h b/chrome/browser/extensions/scripting_permissions_modifier.h
index 82758cc..1b4a5680 100644
--- a/chrome/browser/extensions/scripting_permissions_modifier.h
+++ b/chrome/browser/extensions/scripting_permissions_modifier.h
@@ -53,13 +53,13 @@
   // be granted, populating |granted_permissions_out| with the set of all
   // permissions that can be granted, and |withheld_permissions_out| with the
   // set of all withheld permissions.
-  // If |check_prefs| is false, this won't take into account preferences like
-  // AllowedScriptingOnAllUrls().
+  // If |use_initial_state| is true, this will treat the extension as though it
+  // was just installed, not taking into account extra granted preferences.
   void WithholdPermissions(
       const PermissionSet& permissions,
       scoped_ptr<const PermissionSet>* granted_permissions_out,
       scoped_ptr<const PermissionSet>* withheld_permissions_out,
-      bool check_prefs) const;
+      bool use_initial_state) const;
 
   // Grants any withheld all-hosts (or all-hosts-like) permissions.
   void GrantWithheldImpliedAllHosts() const;
diff --git a/chrome/browser/extensions/settings_api_bubble_controller.h b/chrome/browser/extensions/settings_api_bubble_controller.h
deleted file mode 100644
index 0e1c620..0000000
--- a/chrome/browser/extensions/settings_api_bubble_controller.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_SETTINGS_API_BUBBLE_CONTROLLER_H_
-#define CHROME_BROWSER_EXTENSIONS_SETTINGS_API_BUBBLE_CONTROLLER_H_
-
-#include <string>
-
-#include "chrome/browser/extensions/extension_message_bubble_controller.h"
-#include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
-
-namespace extensions {
-
-class SettingsApiBubble;
-
-class SettingsApiBubbleController : public ExtensionMessageBubbleController {
- public:
-  SettingsApiBubbleController(Browser* browser, SettingsApiOverrideType type);
-  ~SettingsApiBubbleController() override;
-
-  // ExtensionMessageBubbleController:
-  bool CloseOnDeactivate() override;
-
- private:
-  // The type of settings override this bubble will report on.
-  SettingsApiOverrideType type_;
-
-  DISALLOW_COPY_AND_ASSIGN(SettingsApiBubbleController);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_SETTINGS_API_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/extensions/settings_api_bubble_controller.cc b/chrome/browser/extensions/settings_api_bubble_delegate.cc
similarity index 78%
rename from chrome/browser/extensions/settings_api_bubble_controller.cc
rename to chrome/browser/extensions/settings_api_bubble_delegate.cc
index 8ffef42c..2641883f 100644
--- a/chrome/browser/extensions/settings_api_bubble_controller.cc
+++ b/chrome/browser/extensions/settings_api_bubble_delegate.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/extensions/settings_api_bubble_controller.h"
+#include "chrome/browser/extensions/settings_api_bubble_delegate.h"
 
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
@@ -29,47 +29,7 @@
 // the user's settings (homepage, startup pages, or search engine).
 const char kSettingsBubbleAcknowledged[] = "ack_settings_bubble";
 
-////////////////////////////////////////////////////////////////////////////////
-// SettingsApiBubbleDelegate
-
-class SettingsApiBubbleDelegate
-    : public ExtensionMessageBubbleController::Delegate {
- public:
-  SettingsApiBubbleDelegate(Profile* profile, SettingsApiOverrideType type);
-  ~SettingsApiBubbleDelegate() override;
-
-  // ExtensionMessageBubbleController::Delegate methods.
-  bool ShouldIncludeExtension(const Extension* extension) override;
-  void AcknowledgeExtension(
-      const std::string& extension_id,
-      ExtensionMessageBubbleController::BubbleAction user_action) override;
-  void PerformAction(const ExtensionIdList& list) override;
-  base::string16 GetTitle() const override;
-  base::string16 GetMessageBody(bool anchored_to_browser_action,
-                                int extension_count) const override;
-  base::string16 GetOverflowText(
-      const base::string16& overflow_count) const override;
-  GURL GetLearnMoreUrl() const override;
-  base::string16 GetActionButtonLabel() const override;
-  base::string16 GetDismissButtonLabel() const override;
-  bool ShouldShowExtensionList() const override;
-  bool ShouldHighlightExtensions() const override;
-  bool ShouldLimitToEnabledExtensions() const override;
-  void LogExtensionCount(size_t count) override;
-  void LogAction(
-      ExtensionMessageBubbleController::BubbleAction action) override;
-
- private:
-  // The type of settings override this bubble will report on. This can be, for
-  // example, a bubble to notify the user that the search engine has been
-  // changed by an extension (or homepage/startup pages/etc).
-  SettingsApiOverrideType type_;
-
-  // The ID of the extension we are showing the bubble for.
-  std::string extension_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(SettingsApiBubbleDelegate);
-};
+}  // namespace
 
 SettingsApiBubbleDelegate::SettingsApiBubbleDelegate(
     Profile* profile,
@@ -233,6 +193,12 @@
   return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
 }
 
+bool SettingsApiBubbleDelegate::ShouldCloseOnDeactivate() const {
+  // Startup bubbles tend to get lost in the focus storm that happens on
+  // startup. Other types should dismiss on focus loss.
+  return type_ != BUBBLE_TYPE_STARTUP_PAGES;
+}
+
 bool SettingsApiBubbleDelegate::ShouldShowExtensionList() const {
   return false;
 }
@@ -272,25 +238,4 @@
   }
 }
 
-}  // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// SettingsApiBubbleController
-
-SettingsApiBubbleController::SettingsApiBubbleController(
-    Browser* browser,
-    SettingsApiOverrideType type)
-    : ExtensionMessageBubbleController(
-          new SettingsApiBubbleDelegate(browser->profile(), type),
-          browser),
-      type_(type) {}
-
-SettingsApiBubbleController::~SettingsApiBubbleController() {}
-
-bool SettingsApiBubbleController::CloseOnDeactivate() {
-  // Startup bubbles tend to get lost in the focus storm that happens on
-  // startup. Other types should dismiss on focus loss.
-  return type_ != BUBBLE_TYPE_STARTUP_PAGES;
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/settings_api_bubble_delegate.h b/chrome/browser/extensions/settings_api_bubble_delegate.h
new file mode 100644
index 0000000..dde081d3
--- /dev/null
+++ b/chrome/browser/extensions/settings_api_bubble_delegate.h
@@ -0,0 +1,57 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_SETTINGS_API_BUBBLE_DELEGATE_H_
+#define CHROME_BROWSER_EXTENSIONS_SETTINGS_API_BUBBLE_DELEGATE_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/extensions/extension_message_bubble_controller.h"
+#include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
+
+namespace extensions {
+
+class SettingsApiBubbleDelegate
+    : public ExtensionMessageBubbleController::Delegate {
+ public:
+  SettingsApiBubbleDelegate(Profile* profile, SettingsApiOverrideType type);
+  ~SettingsApiBubbleDelegate() override;
+
+  // ExtensionMessageBubbleController::Delegate methods.
+  bool ShouldIncludeExtension(const Extension* extension) override;
+  void AcknowledgeExtension(
+      const std::string& extension_id,
+      ExtensionMessageBubbleController::BubbleAction user_action) override;
+  void PerformAction(const ExtensionIdList& list) override;
+  base::string16 GetTitle() const override;
+  base::string16 GetMessageBody(bool anchored_to_browser_action,
+                                int extension_count) const override;
+  base::string16 GetOverflowText(
+      const base::string16& overflow_count) const override;
+  GURL GetLearnMoreUrl() const override;
+  base::string16 GetActionButtonLabel() const override;
+  base::string16 GetDismissButtonLabel() const override;
+  bool ShouldCloseOnDeactivate() const override;
+  bool ShouldShowExtensionList() const override;
+  bool ShouldHighlightExtensions() const override;
+  bool ShouldLimitToEnabledExtensions() const override;
+  void LogExtensionCount(size_t count) override;
+  void LogAction(ExtensionMessageBubbleController::BubbleAction) override;
+
+ private:
+  // The type of settings override this bubble will report on. This can be, for
+  // example, a bubble to notify the user that the search engine has been
+  // changed by an extension (or homepage/startup pages/etc).
+  SettingsApiOverrideType type_;
+
+  // The ID of the extension we are showing the bubble for.
+  std::string extension_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(SettingsApiBubbleDelegate);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_SETTINGS_API_BUBBLE_DELEGATE_H_
diff --git a/chrome/browser/extensions/suspicious_extension_bubble_controller.h b/chrome/browser/extensions/suspicious_extension_bubble_controller.h
deleted file mode 100644
index 1f0102c..0000000
--- a/chrome/browser/extensions/suspicious_extension_bubble_controller.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_SUSPICIOUS_EXTENSION_BUBBLE_CONTROLLER_H_
-#define CHROME_BROWSER_EXTENSIONS_SUSPICIOUS_EXTENSION_BUBBLE_CONTROLLER_H_
-
-#include "chrome/browser/extensions/extension_message_bubble_controller.h"
-
-class Browser;
-
-namespace extensions {
-
-class SuspiciousExtensionBubbleController
-    : public extensions::ExtensionMessageBubbleController {
- public:
-  // Clears the list of profiles the bubble has been shown for. Should only be
-  // used during testing.
-  static void ClearProfileListForTesting();
-
-  explicit SuspiciousExtensionBubbleController(Browser* browser);
-  ~SuspiciousExtensionBubbleController() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SuspiciousExtensionBubbleController);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_SUSPICIOUS_EXTENSION_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/extensions/suspicious_extension_bubble_controller.cc b/chrome/browser/extensions/suspicious_extension_bubble_delegate.cc
similarity index 68%
rename from chrome/browser/extensions/suspicious_extension_bubble_controller.cc
rename to chrome/browser/extensions/suspicious_extension_bubble_delegate.cc
index 29652e6..c4b95ed 100644
--- a/chrome/browser/extensions/suspicious_extension_bubble_controller.cc
+++ b/chrome/browser/extensions/suspicious_extension_bubble_delegate.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
+#include "chrome/browser/extensions/suspicious_extension_bubble_delegate.h"
 
 #include "base/lazy_instance.h"
 #include "base/metrics/histogram.h"
@@ -29,40 +29,9 @@
 base::LazyInstance<std::set<Profile*> > g_shown_for_profiles =
   LAZY_INSTANCE_INITIALIZER;
 
-////////////////////////////////////////////////////////////////////////////////
-// SuspiciousExtensionBubbleDelegate
+}  // namespace
 
-class SuspiciousExtensionBubbleDelegate
-    : public ExtensionMessageBubbleController::Delegate {
- public:
-  explicit SuspiciousExtensionBubbleDelegate(Profile* profile);
-  ~SuspiciousExtensionBubbleDelegate() override;
-
-  // ExtensionMessageBubbleController::Delegate methods.
-  bool ShouldIncludeExtension(const extensions::Extension* extension) override;
-  void AcknowledgeExtension(
-      const std::string& extension_id,
-      ExtensionMessageBubbleController::BubbleAction user_action) override;
-  void PerformAction(const extensions::ExtensionIdList& list) override;
-  base::string16 GetTitle() const override;
-  base::string16 GetMessageBody(bool anchored_to_browser_action,
-                                int extension_count) const override;
-  base::string16 GetOverflowText(
-      const base::string16& overflow_count) const override;
-  GURL GetLearnMoreUrl() const override;
-  base::string16 GetActionButtonLabel() const override;
-  base::string16 GetDismissButtonLabel() const override;
-  bool ShouldShowExtensionList() const override;
-  bool ShouldHighlightExtensions() const override;
-  bool ShouldLimitToEnabledExtensions() const override;
-  void LogExtensionCount(size_t count) override;
-  void LogAction(
-      ExtensionMessageBubbleController::BubbleAction action) override;
-  std::set<Profile*>* GetProfileSet() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SuspiciousExtensionBubbleDelegate);
-};
+namespace extensions {
 
 SuspiciousExtensionBubbleDelegate::SuspiciousExtensionBubbleDelegate(
     Profile* profile)
@@ -134,6 +103,10 @@
   return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BUTTON);
 }
 
+bool SuspiciousExtensionBubbleDelegate::ShouldCloseOnDeactivate() const {
+  return false;
+}
+
 bool SuspiciousExtensionBubbleDelegate::ShouldShowExtensionList() const {
   return true;
 }
@@ -163,25 +136,9 @@
   return g_shown_for_profiles.Pointer();
 }
 
-}  // namespace
-
-namespace extensions {
-
-////////////////////////////////////////////////////////////////////////////////
-// SuspiciousExtensionBubbleController
-
 // static
-void SuspiciousExtensionBubbleController::ClearProfileListForTesting() {
+void SuspiciousExtensionBubbleDelegate::ClearProfileListForTesting() {
   g_shown_for_profiles.Get().clear();
 }
 
-SuspiciousExtensionBubbleController::SuspiciousExtensionBubbleController(
-    Browser* browser)
-    : ExtensionMessageBubbleController(
-          new SuspiciousExtensionBubbleDelegate(browser->profile()),
-          browser) {}
-
-SuspiciousExtensionBubbleController::~SuspiciousExtensionBubbleController() {
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/suspicious_extension_bubble_delegate.h b/chrome/browser/extensions/suspicious_extension_bubble_delegate.h
new file mode 100644
index 0000000..9ecad2668
--- /dev/null
+++ b/chrome/browser/extensions/suspicious_extension_bubble_delegate.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_SUSPICIOUS_EXTENSION_BUBBLE_DELEGATE_H_
+#define CHROME_BROWSER_EXTENSIONS_SUSPICIOUS_EXTENSION_BUBBLE_DELEGATE_H_
+
+#include "base/macros.h"
+#include "chrome/browser/extensions/extension_message_bubble_controller.h"
+
+class Browser;
+
+namespace extensions {
+
+class SuspiciousExtensionBubbleDelegate
+    : public ExtensionMessageBubbleController::Delegate {
+ public:
+  explicit SuspiciousExtensionBubbleDelegate(Profile* profile);
+  ~SuspiciousExtensionBubbleDelegate() override;
+
+  // ExtensionMessageBubbleController::Delegate methods.
+  bool ShouldIncludeExtension(const extensions::Extension* extension) override;
+  void AcknowledgeExtension(
+      const std::string& extension_id,
+      ExtensionMessageBubbleController::BubbleAction user_action) override;
+  void PerformAction(const extensions::ExtensionIdList& list) override;
+  base::string16 GetTitle() const override;
+  base::string16 GetMessageBody(bool anchored_to_browser_action,
+                                int extension_count) const override;
+  base::string16 GetOverflowText(
+      const base::string16& overflow_count) const override;
+  GURL GetLearnMoreUrl() const override;
+  base::string16 GetActionButtonLabel() const override;
+  base::string16 GetDismissButtonLabel() const override;
+  bool ShouldCloseOnDeactivate() const override;
+  bool ShouldShowExtensionList() const override;
+  bool ShouldHighlightExtensions() const override;
+  bool ShouldLimitToEnabledExtensions() const override;
+  void LogExtensionCount(size_t count) override;
+  void LogAction(ExtensionMessageBubbleController::BubbleAction) override;
+  std::set<Profile*>* GetProfileSet() override;
+
+  // Clears the list of profiles the bubble has been shown for. Should only be
+  // used during testing.
+  static void ClearProfileListForTesting();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SuspiciousExtensionBubbleDelegate);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_SUSPICIOUS_EXTENSION_BUBBLE_DELEGATE_H_
diff --git a/chrome/browser/first_run/first_run_internal_posix.cc b/chrome/browser/first_run/first_run_internal_posix.cc
index eec6d162..6fb649f 100644
--- a/chrome/browser/first_run/first_run_internal_posix.cc
+++ b/chrome/browser/first_run/first_run_internal_posix.cc
@@ -16,7 +16,7 @@
 #include "chrome/installer/util/google_update_settings.h"
 #include "chrome/installer/util/master_preferences.h"
 #include "components/metrics/metrics_pref_names.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 
 namespace first_run {
 namespace internal {
diff --git a/chrome/browser/guest_view/chrome_guest_view_manager_delegate.cc b/chrome/browser/guest_view/chrome_guest_view_manager_delegate.cc
index 2612276..886e2ea 100644
--- a/chrome/browser/guest_view/chrome_guest_view_manager_delegate.cc
+++ b/chrome/browser/guest_view/chrome_guest_view_manager_delegate.cc
@@ -6,6 +6,11 @@
 
 #include "chrome/browser/task_management/web_contents_tags.h"
 
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/app_mode/app_session.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
+#endif
+
 namespace extensions {
 
 ChromeGuestViewManagerDelegate::ChromeGuestViewManagerDelegate(
@@ -16,9 +21,20 @@
 ChromeGuestViewManagerDelegate::~ChromeGuestViewManagerDelegate() {
 }
 
-void ChromeGuestViewManagerDelegate::AttachTaskManagerGuestTag(
+void ChromeGuestViewManagerDelegate::OnGuestAdded(
     content::WebContents* guest_web_contents) const {
+  // Attaches the task-manager-specific tag for the GuestViews to its
+  // |guest_web_contents| so that their corresponding tasks show up in the task
+  // manager.
   task_management::WebContentsTags::CreateForGuestContents(guest_web_contents);
+
+#if defined(OS_CHROMEOS)
+  // Notifies kiosk session about the added guest.
+  chromeos::AppSession* app_session =
+      chromeos::KioskAppManager::Get()->app_session();
+  if (app_session)
+    app_session->OnGuestAdded(guest_web_contents);
+#endif
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/guest_view/chrome_guest_view_manager_delegate.h b/chrome/browser/guest_view/chrome_guest_view_manager_delegate.h
index b2f345f..2b31108 100644
--- a/chrome/browser/guest_view/chrome_guest_view_manager_delegate.h
+++ b/chrome/browser/guest_view/chrome_guest_view_manager_delegate.h
@@ -20,8 +20,7 @@
   ~ChromeGuestViewManagerDelegate() override;
 
   // GuestViewManagerDelegate:
-  void AttachTaskManagerGuestTag(
-      content::WebContents* guest_web_contents) const override;
+  void OnGuestAdded(content::WebContents* guest_web_contents) const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ChromeGuestViewManagerDelegate);
diff --git a/chrome/browser/mac/mac_startup_profiler.cc b/chrome/browser/mac/mac_startup_profiler.cc
index 95aa7d8d..37d247b 100644
--- a/chrome/browser/mac/mac_startup_profiler.cc
+++ b/chrome/browser/mac/mac_startup_profiler.cc
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 
 // static
 MacStartupProfiler* MacStartupProfiler::GetInstance() {
diff --git a/chrome/browser/metrics/first_web_contents_profiler.cc b/chrome/browser/metrics/first_web_contents_profiler.cc
index 17662e9..1b3a6800 100644
--- a/chrome/browser/metrics/first_web_contents_profiler.cc
+++ b/chrome/browser/metrics/first_web_contents_profiler.cc
@@ -17,7 +17,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "components/metrics/profiler/tracking_synchronizer.h"
 #include "components/metrics/proto/profiler_event.pb.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "content/public/browser/navigation_handle.h"
 
 scoped_ptr<FirstWebContentsProfiler>
diff --git a/chrome/browser/plugins/plugin_power_saver_browsertest.cc b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
index fce95a5..dff34a9 100644
--- a/chrome/browser/plugins/plugin_power_saver_browsertest.cc
+++ b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
@@ -219,11 +219,7 @@
                                 const SkBitmap& bitmap,
                                 content::ReadbackResponse response) {
   DCHECK(snapshot_matches);
-  if (response != content::READBACK_SUCCESS) {
-    *snapshot_matches = false;
-    done_cb.Run();
-    return;
-  }
+  ASSERT_EQ(content::READBACK_SUCCESS, response);
 
   *snapshot_matches = SnapshotMatches(reference, bitmap);
 
@@ -275,6 +271,12 @@
         switches::kOverridePluginPowerSaverForTesting, "ignore-list");
 
     ASSERT_TRUE(ppapi::RegisterPowerSaverTestPlugin(command_line));
+
+#if !defined(OS_CHROMEOS)
+    // These pixel tests are flaky on MSan bots with hardware rendering.
+    // However, ChromeOS does not support software compositing.
+    command_line->AppendSwitch(switches::kDisableGpu);
+#endif
   }
 
  protected:
@@ -321,6 +323,13 @@
   }
 
   bool VerifySnapshot(const base::FilePath::StringType& expected_filename) {
+#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
+    // Because we cannot use hardware OpenGL under MSan, but also cannot use
+    // software rendering under ChromeOS, we skip this portion of the test.
+    // See crbug.com/512140
+    return true;
+#endif
+
     base::FilePath reference = ui_test_utils::GetTestFilePath(
         base::FilePath(FILE_PATH_LITERAL("plugin_power_saver")),
         base::FilePath(expected_filename));
@@ -333,11 +342,10 @@
     content::RenderWidgetHost* rwh =
         GetActiveWebContents()->GetRenderViewHost()->GetWidget();
 
-    // When a widget is first shown, it can take some time before it is ready
-    // for copying from its backing store.  This is a transient condition, and
-    // so it is not being treated as a test failure.
-    if (!rwh->CanCopyFromBackingStore())
+    if (!rwh->CanCopyFromBackingStore()) {
+      ADD_FAILURE() << "Could not copy from backing store.";
       return false;
+    }
 
     bool snapshot_matches = false;
     rwh->CopyFromBackingStore(
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 82324f08..5f41c923 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -707,6 +707,9 @@
 
 // TODO(nparker): Switch this to use TestSafeBrowsingDatabaseManager and run
 // with SAFE_BROWSING_DB_LOCAL || SAFE_BROWSING_DB_REMOTE.
+// Note: don't forget to override GetProtocolManagerDelegate and return NULL,
+// because FakeSafeBrowsingDatabaseManager does not implement
+// LocalSafeBrowsingDatabaseManager.
 #if defined(FULL_SAFE_BROWSING)
 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
 // a given URL.
@@ -755,7 +758,7 @@
         std::vector<GURL>(1, gurl),
         std::vector<SBFullHash>(),
         client,
-        safe_browsing_util::MALWARE,
+        safe_browsing::MALWARE,
         expected_threats);
     sb_check.url_results[0] = threat_type_;
     sb_check.OnSafeBrowsingResult();
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index f66d796..2b16ce3 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -890,7 +890,8 @@
             profile_info_cache.GetPathOfProfileAtIndex(profile_index);
         Profile* profile = profile_manager->GetProfileByPath(profile_path);
         if ((profile != GetProfile()) &&
-            !profile_info_cache.IsOmittedProfileAtIndex(profile_index)) {
+            !profile_info_cache.IsOmittedProfileAtIndex(profile_index) &&
+            !profile_info_cache.ProfileIsSigninRequiredAtIndex(profile_index)) {
           target_profiles.push_back(profile_index);
         }
       }
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb
index 699ee2ca..d437354 100644
--- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb
+++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_fa.xtb
@@ -15,7 +15,7 @@
 <translation id="1120743664840974483">{«ا»: «اسب»، «ب»: «بازی»، «پ»: «پروین»، «ت»: «ترانه»، «ث»: «ثریا»، «ج»: «جوجه»، «چ»: «چرخ»، «ح»: «حریم»، « خ»:«خصوصی »، « د»: «دفترچه»، «ذ»: «ذلیل»، «ر»: «روز»، «ز»: «زمان»، «ژ»: «ژولیت»، «س»: «سیاست»، «ش»: «شنبه»، «ص»: «صفحه»، «ض»: «ضروری»، «ط»: «طراوت»، «ظ»: «ظهر»، «ع»: «عصر»، « غ»: «غروب»، «ف»: «فروش»، «ق»: «قلب»، «ک»: «کودکان»، «گ»: «گوشی»، «ل»: «لوله»، «م»: «مرز»، «ن»: «نامناسب»، «و»: «ویلا»، «ه»: «هیاهو»، «ی»: «یادآور»}</translation>
 <translation id="113582498867142724">مجموعه <ph name="TAG" /> با <ph name="NUM" /> مورد</translation>
 <translation id="1155043339247954670">مورد لیست بعدی وجود ندارد.</translation>
-<translation id="1157782847298808853">راهنمای صفحه کلید</translation>
+<translation id="1157782847298808853">راهنمای صفحه‌کلید</translation>
 <translation id="1157843803349774103"><ph name="VALUE" />، <ph name="NAME" />، کادر ترکیبی</translation>
 <translation id="1167230103353892028"><ph name="NAME" />، مورد منو، با منوی فرعی</translation>
 <translation id="1177863135347784049">سفارشی</translation>
@@ -570,7 +570,7 @@
 <translation id="7161771961008409533">دکمه بازشو</translation>
 <translation id="7167657087543110">بازگویی نویسه</translation>
 <translation id="7170733337935166589">در حین مطالعه متوالی، به جلو بروید</translation>
-<translation id="7181697990050180700">میانبرهای صفحه‌کلید را برای فرمان‌هایی که اغلب استفاده می‌شوند با تایپ کردن آنها در قسمت‌های مربوطه در زیر سفارشی کنید.</translation>
+<translation id="7181697990050180700">میان‌برهای صفحه‌کلید را برای فرمان‌هایی که اغلب استفاده می‌شوند با تایپ کردن آنها در قسمت‌های مربوطه در زیر سفارشی کنید.</translation>
 <translation id="7203150201908454328">باز شده</translation>
 <translation id="7210211103303402262">دقیقه</translation>
 <translation id="7217912842225915592">‎+<ph name="NUM" /></translation>
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_login.html b/chrome/browser/resources/chromeos/login/custom_elements_login.html
index a769e997..7949e486 100644
--- a/chrome/browser/resources/chromeos/login/custom_elements_login.html
+++ b/chrome/browser/resources/chromeos/login/custom_elements_login.html
@@ -7,5 +7,6 @@
 <include src="offline_gaia.html">
 <include src="saml_confirm_password.html">
 <include src="throbber_notice.html">
+<include src="navigation_bar.html">
 
 <script src="chrome://oobe/custom_elements.js"></script>
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_login.js b/chrome/browser/resources/chromeos/login/custom_elements_login.js
index f2fa0943..f201492 100644
--- a/chrome/browser/resources/chromeos/login/custom_elements_login.js
+++ b/chrome/browser/resources/chromeos/login/custom_elements_login.js
@@ -11,3 +11,4 @@
 <include src="offline_gaia.js">
 <include src="saml_confirm_password.js">
 <include src="throbber_notice.js">
+<include src="navigation_bar.js">
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_oobe.html b/chrome/browser/resources/chromeos/login/custom_elements_oobe.html
index 92c1e5e..155384a 100644
--- a/chrome/browser/resources/chromeos/login/custom_elements_oobe.html
+++ b/chrome/browser/resources/chromeos/login/custom_elements_oobe.html
@@ -12,5 +12,6 @@
 <include src="oobe-screen.html">
 <include src="saml_confirm_password.html">
 <include src="throbber_notice.html">
+<include src="navigation_bar.html">
 
 <script src="chrome://oobe/custom_elements.js"></script>
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_oobe.js b/chrome/browser/resources/chromeos/login/custom_elements_oobe.js
index b875dd9c..2c43a5e 100644
--- a/chrome/browser/resources/chromeos/login/custom_elements_oobe.js
+++ b/chrome/browser/resources/chromeos/login/custom_elements_oobe.js
@@ -19,3 +19,4 @@
 <include src="offline_gaia.js">
 <include src="saml_confirm_password.js">
 <include src="throbber_notice.js">
+<include src="navigation_bar.js">
diff --git a/chrome/browser/resources/chromeos/login/gaia_password_changed.css b/chrome/browser/resources/chromeos/login/gaia_password_changed.css
index 37c6b567..a4f9304 100644
--- a/chrome/browser/resources/chromeos/login/gaia_password_changed.css
+++ b/chrome/browser/resources/chromeos/login/gaia_password_changed.css
@@ -9,23 +9,18 @@
 }
 
 iron-icon[icon='warning'] {
+  -webkit-margin-end: 15px;
+  -webkit-margin-start: 0;
   color: var(--google-yellow-500);
-  margin: 0 15px 0 0;
+  margin-bottom: 0;
+  margin-top: 0;
 }
 
-:host-context(html[dir=rtl]) iron-icon[icon='warning'] {
-  margin: 0 0 0 15px;
-}
-
-#closeButton {
+#navigation {
   color: white;
+  left: 0;
   position: absolute;
-  right: 10px;
-  top: 10px;
+  right: 0;
+  top: 0;
   z-index: 1;
 }
-
-:host-context(html[dir=rtl]) #closeButton {
-  left: 10px;
-  right: auto;
-}
diff --git a/chrome/browser/resources/chromeos/login/gaia_password_changed.html b/chrome/browser/resources/chromeos/login/gaia_password_changed.html
index 290cc0e..dfb994a 100644
--- a/chrome/browser/resources/chromeos/login/gaia_password_changed.html
+++ b/chrome/browser/resources/chromeos/login/gaia_password_changed.html
@@ -93,9 +93,9 @@
         </throbber-notice>
       </neon-animatable>
     </neon-animated-pages>
-    <gaia-icon-button id="closeButton" icon="close" on-tap="onClose_"
-        disabled="[[disabled]]" i18n-values="aria-label:closeButton">
-    </gaia-icon-button>
+    <navigation-bar id="navigation" disabled="[[disabled]]" close-visible
+        on-close="onClose_">
+    </navigation-bar>
   </template>
 </dom-module>
 
diff --git a/chrome/browser/resources/chromeos/login/gaia_password_changed.js b/chrome/browser/resources/chromeos/login/gaia_password_changed.js
index 033ca4b..5206090 100644
--- a/chrome/browser/resources/chromeos/login/gaia_password_changed.js
+++ b/chrome/browser/resources/chromeos/login/gaia_password_changed.js
@@ -35,7 +35,7 @@
     this.clearPassword();
     this.$.oldPasswordInput.isInvalid = false;
     this.disabled = false;
-    this.$.closeButton.hidden = false;
+    this.$.navigation.closeVisible = true;
     this.$.oldPasswordCard.classList.remove('disabled');
   },
 
@@ -73,7 +73,7 @@
 
   onProceedClicked_: function() {
     this.disabled = true;
-    this.$.closeButton.hidden = true;
+    this.$.navigation.closeVisible = false;
     this.$.animatedPages.selected = 2;
     this.fire('proceedAnyway');
   },
diff --git a/chrome/browser/resources/chromeos/login/header_bar.js b/chrome/browser/resources/chromeos/login/header_bar.js
index 723fa68..337d3f5 100644
--- a/chrome/browser/resources/chromeos/login/header_bar.js
+++ b/chrome/browser/resources/chromeos/login/header_bar.js
@@ -290,11 +290,11 @@
     updateUI_: function() {
       var gaiaIsActive = (this.signinUIState_ == SIGNIN_UI_STATE.GAIA_SIGNIN);
       var gaiaIsActiveWithBackButton =
-          gaiaIsActive && !$('back-button-item').hidden;
+          gaiaIsActive && $('gaia-navigation').backVisible;
       var enrollmentIsActive =
           (this.signinUIState_ == SIGNIN_UI_STATE.ENROLLMENT);
       var enrollmentIsActiveWithBackButton =
-          enrollmentIsActive && !$('oauth-enroll-back-button').hidden;
+          enrollmentIsActive && $('oauth-enroll-navigation').backVisible;
       var accountPickerIsActive =
           (this.signinUIState_ == SIGNIN_UI_STATE.ACCOUNT_PICKER);
       var supervisedUserCreationDialogIsActive =
diff --git a/chrome/browser/resources/chromeos/login/navigation_bar.css b/chrome/browser/resources/chromeos/login/navigation_bar.css
new file mode 100644
index 0000000..465b178a
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/navigation_bar.css
@@ -0,0 +1,20 @@
+/* Copyright 2015 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+:host {
+  display: block;
+  height: calc(2 * 10px + 24px); /* Buttons' height is 24px. */
+  min-width: 100px;
+  position: relative;
+}
+
+gaia-icon-button {
+  margin: 0 10px;
+}
+
+:host-context(html[dir='rtl']) #backButton {
+  transform: scaleX(-1);
+}
+
diff --git a/chrome/browser/resources/chromeos/login/navigation_bar.html b/chrome/browser/resources/chromeos/login/navigation_bar.html
new file mode 100644
index 0000000..60a3ab3c
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/navigation_bar.html
@@ -0,0 +1,46 @@
+<!-- Copyright 2015 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
+
+
+<!--
+  A navigation panel with back, refresh, and/or close buttons.
+  ┌─────────────────────────────────┐
+  │ <-                         ↻  X │
+  └─────────────────────────────────┘
+
+  Example:
+    <navigation-bar close-visible back-visible></navigation-bar>
+
+  Propertites:
+     '{back,refresh,close}Visible' - change visiblility of corresponding
+                                     buttons.
+     'disable' - if true, all the buttons are disabled.
+
+  Events:
+     'back', 'refresh', 'close' - fired when corresponding buttons are clicked.
+
+-->
+<dom-module id="navigation-bar">
+  <link rel="stylesheet" href="navigation_bar.css">
+
+  <template>
+    <div class="fit layout horizontal center">
+      <gaia-icon-button id="backButton" icon="arrow-back"
+          hidden="[[!backVisible]]" disabled="[[disabled]]" on-tap="onBack_"
+          i18n-values="aria-label:backButton">
+      </gaia-icon-button>
+      <div class="flex"></div>
+      <gaia-icon-button id="refreshButton" icon="refresh"
+          hidden="[[!refreshVisible]]" disabled="[[disabled]]"
+          on-tap="onRefresh_" i18n-values="aria-label:closeButton">
+      </gaia-icon-button>
+      <gaia-icon-button id="closeButton" icon="close" hidden="[[!closeVisible]]"
+          disabled="[[disabled]]" on-tap="onClose_"
+          i18n-values="aria-label:closeButton">
+      </gaia-icon-button>
+    </div>
+  </template>
+</dom-module>
diff --git a/chrome/browser/resources/chromeos/login/navigation_bar.js b/chrome/browser/resources/chromeos/login/navigation_bar.js
new file mode 100644
index 0000000..c428afc
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/navigation_bar.js
@@ -0,0 +1,30 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Polymer({
+  is: 'navigation-bar',
+
+  properties: {
+    backVisible: {
+      type: Boolean,
+      value: false
+    },
+    closeVisible: {
+      type: Boolean,
+      value: false
+    },
+    refreshVisible: {
+      type: Boolean,
+      value: false
+    },
+    disabled: {
+      type: Boolean,
+      value: false
+    }
+  },
+
+  onBack_: function() { this.fire('back'); },
+  onClose_: function() { this.fire('close'); },
+  onRefresh_: function() { this.fire('refresh'); }
+});
diff --git a/chrome/browser/resources/chromeos/login/offline_gaia.css b/chrome/browser/resources/chromeos/login/offline_gaia.css
index fc1545d..45a78ec4 100644
--- a/chrome/browser/resources/chromeos/login/offline_gaia.css
+++ b/chrome/browser/resources/chromeos/login/offline_gaia.css
@@ -11,20 +11,6 @@
   position: relative;
 }
 
-#backButton {
-  color: white;
-  left: 10px;
-  position: absolute;
-  top: 10px;
-  z-index: 1;
-}
-
-:host-context(html[dir=rtl]) #backButton {
-  left: auto;
-  right: 10px;
-  transform: scaleX(-1);
-}
-
 paper-dialog {
   --paper-dialog-title: {
     font-size: 15px;
diff --git a/chrome/browser/resources/chromeos/login/offline_gaia.html b/chrome/browser/resources/chromeos/login/offline_gaia.html
index 32a262c..717282c1 100644
--- a/chrome/browser/resources/chromeos/login/offline_gaia.html
+++ b/chrome/browser/resources/chromeos/login/offline_gaia.html
@@ -92,10 +92,6 @@
       </neon-animatable>
     </neon-animated-pages>
 
-    <gaia-icon-button id="backButton" icon="arrow-back" disabled="[[disabled]]"
-        on-tap="onBack_" hidden>
-    </gaia-icon-button>
-
     <paper-dialog id="forgotPasswordDlg" no-cancel-on-outside-click
         on-iron-overlay-closed="onDialogOverlayClosed_">
       <p i18n-content="offlineLoginForgotPasswordDlg"></p>
diff --git a/chrome/browser/resources/chromeos/login/offline_gaia.js b/chrome/browser/resources/chromeos/login/offline_gaia.js
index 25a258d..76993ff 100644
--- a/chrome/browser/resources/chromeos/login/offline_gaia.js
+++ b/chrome/browser/resources/chromeos/login/offline_gaia.js
@@ -31,11 +31,6 @@
           { get: function() { return false; } });
     },
 
-    onAnimationFinish_: function() {
-      this.$.backButton.hidden = this.isEmailSectionActive_();
-      this.focus();
-    },
-
     focus: function() {
       if (this.isEmailSectionActive_())
         this.$.emailInput.focus();
@@ -43,15 +38,26 @@
         this.$.passwordInput.focus();
     },
 
+    back: function() {
+      this.switchToEmailCard();
+    },
+
+    onAnimationFinish_: function() {
+      this.fire('backButton', !this.isEmailSectionActive_());
+      this.focus();
+    },
+
     onForgotPasswordClicked_: function() {
       this.$.forgotPasswordDlg.fitInto = this;
       this.disabled = true;
+      this.fire('dialogShown');
       this.$.forgotPasswordDlg.open();
       this.$.passwordCard.classList.add('full-disabled');
       this.$.forgotPasswordDlg.focus();
     },
 
     onDialogOverlayClosed_: function() {
+      this.fire('dialogHidden');
       this.disabled = false;
       this.$.passwordCard.classList.remove('full-disabled');
     },
@@ -68,11 +74,6 @@
       }
     },
 
-    onBack_: function() {
-      this.$.backButton.hidden = true;
-      this.switchToEmailCard();
-    },
-
     isRTL_: function() {
       return !!document.querySelector('html[dir=rtl]');
     },
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css
index 4199dc4c..1f2b525 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css
@@ -50,9 +50,7 @@
   width: 100%;
 }
 
-#oauth-enrollment.mode-manual #oauth-enroll-learn-more-link,
-#oauth-enrollment.mode-forced #oauth-enroll-learn-more-link,
-#oauth-enrollment.mode-recovery #oauth-enroll-learn-more-link {
+#oauth-enroll-learn-more-link {
   display: inline;
 }
 
@@ -78,31 +76,6 @@
   display: none;
 }
 
-#oauth-enroll-back-button,
-#oauth-enrollment.saml #oauth-enroll-back-button {
-  display: none;
-}
-
-.oauth-enroll-state-signin #oauth-enroll-back-button {
-  display: inline;
-}
-
-.oauth-enroll-state-signin.mode-manual #oauth-enroll-cancel-button,
-.oauth-enroll-state-signin.mode-forced #oauth-enroll-refresh-button,
-.oauth-enroll-state-signin.mode-recovery #oauth-enroll-refresh-button,
-.oauth-enroll-state-working.mode-manual #oauth-enroll-cancel-button,
-.oauth-enroll-state-working.mode-forced #oauth-enroll-refresh-button,
-.oauth-enroll-state-working.mode-recovery #oauth-enroll-refresh-button,
-.oauth-enroll-state-error.mode-manual #oauth-enroll-cancel-button,
-.oauth-enroll-state-error.mode-manual #oauth-enroll-done-button,
-.oauth-enroll-state-success #oauth-enroll-done-button {
-  display: inline;
-}
-
-#oobe.oauth-enrollment #header-oauth-enrollment {
-  display: block;
-}
-
 #oauth-saml-notice-container {
   -webkit-margin-start: 19px;
   left: 0;
@@ -112,11 +85,6 @@
   top: 15px;
 }
 
-#oauth-enrollment.saml #oauth-enrollment-controls,
-#oauth-enrollment.saml #oauth-enroll-signin-link-container {
-  -webkit-padding-end: 17px;
-}
-
 #oauth-enrollment:not(.saml) #oauth-saml-notice-container {
   display: none;
 }
@@ -127,49 +95,6 @@
   margin: 0 auto;
 }
 
-#oauth-enroll-cancel-button,
-#oauth-enroll-back-button,
-#oauth-enroll-refresh-button {
-  position: absolute;
-  top: 10px;
-  z-index: 1;
-}
-
-#oauth-enroll-cancel-button,
-#oauth-enroll-refresh-button {
-  color: rgba(0, 0, 0, .54);
-  right: 10px;
-}
-
-html[dir=rtl] #oauth-enroll-cancel-button,
-html[dir=rtl] #oauth-enroll-refresh-button {
-  left: 10px;
-  right: auto;
-}
-
-#oauth-enrollment.saml #oauth-enroll-cancel-button,
-#oauth-enrollment.saml #oauth-enroll-refresh-button {
-  color: rgba(0, 0, 0, .54);
-}
-
-.oauth-enroll-state-signin #oauth-enroll-cancel-button,
-.oauth-enroll-state-working #oauth-enroll-cancel-button,
-.oauth-enroll-state-signin #oauth-enroll-refresh-button,
-.oauth-enroll-state-working #oauth-enroll-refresh-button {
-  color: white;
-}
-
-#oauth-enroll-back-button {
-  color: white;
-  left: 10px;
-}
-
-html[dir=rtl] #oauth-enroll-back-button {
-  -webkit-transform: scaleX(-1);
-  left: auto;
-  right: 10px;
-}
-
 #oauth-enroll-attribute-prompt-message {
   color: black;
 }
@@ -177,3 +102,22 @@
 #oauth-enroll-attribute-input {
   padding-top: 24px;
 }
+
+#oauth-enroll-navigation {
+  color: rgba(0, 0, 0, .54);
+  left: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+  z-index: 1;
+}
+
+.oauth-enroll-state-signin #oauth-enroll-navigation,
+.oauth-enroll-state-working #oauth-enroll-navigation {
+  color: white;
+}
+
+#oauth-enrollment.saml #oauth-enroll-navigation {
+  color: rgba(0, 0, 0, .54);
+}
+
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html
index d6612dc..8abb59b0 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html
@@ -61,14 +61,5 @@
   <div id="oauth-saml-notice-container">
     <span id="oauth-saml-notice-message"></span>
   </div>
-  <div id="oauth-enrollment-controls" class="step-controls"></div>
-  <gaia-icon-button id="oauth-enroll-back-button" icon="arrow-back" hidden
-      i18n-values="aria-label:backButton">
-  </gaia-icon-button>
-  <gaia-icon-button id="oauth-enroll-cancel-button" icon="close"
-      class="oauth-enroll-button" i18n-values="aria-label:closeButton">
-  </gaia-icon-button>
-  <gaia-icon-button id="oauth-enroll-refresh-button" icon="refresh"
-      class="oauth-enroll-button" i18n-values="aria-label:closeButton">
-  </gaia-icon-button>
+  <navigation-bar id="oauth-enroll-navigation"></navigation-bar>
 </div>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
index e46a3454..90b59899 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
@@ -47,13 +47,20 @@
 
     get isCancelDisabled() { return this.isCancelDisabled_ },
     set isCancelDisabled(disabled) {
-      if (disabled == this.isCancelDisabled)
-        return;
       this.isCancelDisabled_ = disabled;
     },
 
+    isManualEnrollment_: undefined,
+
+    /**
+     * An element containg navigation buttons.
+     */
+    navigation_: undefined,
+
     /** @override */
     decorate: function() {
+      this.navigation_ = $('oauth-enroll-navigation');
+
       this.authenticator_ =
           new cr.login.Authenticator($('oauth-enroll-auth-view'));
 
@@ -86,6 +93,7 @@
               $('oauth-saml-notice-message').textContent =
                   loadTimeData.getStringF('samlNotice',
                                           this.authenticator_.authDomain);
+              this.navigation_.backVisible = false;
             }
             this.classList.toggle('saml', isSAML);
             if (Oobe.getInstance().currentScreen == this)
@@ -94,7 +102,7 @@
 
       this.authenticator_.addEventListener('backButton',
           (function(e) {
-            $('oauth-enroll-back-button').hidden = !e.detail;
+            this.navigation_.backVisible = !!e.detail;
             $('oauth-enroll-auth-view').focus();
             $('login-header-bar').updateUI_();
           }).bind(this));
@@ -124,17 +132,13 @@
       $('oauth-enroll-success-card').addEventListener(
           'buttonclick', doneCallback);
 
-      $('oauth-enroll-cancel-button').addEventListener('click',
-                                                       this.cancel.bind(this));
-      $('oauth-enroll-refresh-button').addEventListener('click',
-                                                        this.cancel.bind(this));
+      this.navigation_.addEventListener('close', this.cancel.bind(this));
+      this.navigation_.addEventListener('refresh', this.cancel.bind(this));
 
-      $('oauth-enroll-back-button').addEventListener('click',
-          (function(e) {
-            $('oauth-enroll-back-button').hidden = true;
-            $('oauth-enroll-auth-view').back();
-            e.preventDefault();
-          }).bind(this));
+      this.navigation_.addEventListener('back', function() {
+        this.navigation_.backVisible = false;
+        $('oauth-enroll-auth-view').back();
+      }.bind(this));
 
       $('oauth-enroll-attribute-prompt-card').addEventListener('submit',
           this.onAttributesSubmitted.bind(this));
@@ -157,27 +161,6 @@
     },
 
     /**
-     * Buttons in oobe wizard's button strip.
-     * @type {array} Array of Buttons.
-     */
-    get buttons() {
-      var buttons = [];
-      var ownerDocument = this.ownerDocument;
-
-      function makeButton(id, classes, label, handler) {
-        var button = ownerDocument.createElement('button');
-        button.id = id;
-        button.classList.add('oauth-enroll-button');
-        button.classList.add.apply(button.classList, classes);
-        button.textContent = label;
-        button.addEventListener('click', handler);
-        buttons.push(button);
-      }
-
-      return buttons;
-    },
-
-    /**
      * Event handler that is invoked just before the frame is shown.
      * @param {Object} data Screen init payload, contains the signin frame
      * URL.
@@ -198,6 +181,8 @@
 
       $('login-header-bar').signinUIState = SIGNIN_UI_STATE.ENROLLMENT;
       $('progress-dots').hidden = true;
+      this.classList.remove('saml');
+
       var gaiaParams = {};
       gaiaParams.gaiaUrl = data.gaiaUrl;
       gaiaParams.clientId = data.clientId;
@@ -217,7 +202,9 @@
         this.classList.toggle('mode-' + modes[i],
                               data.enrollment_mode == modes[i]);
       }
+      this.isManualEnrollment_ = data.enrollment_mode === 'manual';
       this.isCancelDisabled = true;
+
       this.showStep(STEP_SIGNIN);
     },
 
@@ -232,8 +219,6 @@
     showAttributePromptStep: function(annotated_asset_id, annotated_location) {
       $('oauth-enroll-asset-id').value = annotated_asset_id;
       $('oauth-enroll-location').value = annotated_location;
-      $('oauth-enroll-back-button').hidden = true;
-
       this.showStep(STEP_ATTRIBUTE_PROMPT);
     },
 
@@ -256,6 +241,12 @@
       this.classList.toggle('oauth-enroll-state-' + this.currentStep_, false);
       this.classList.toggle('oauth-enroll-state-' + step, true);
 
+      this.navigation_.backVisible = false;
+      this.navigation_.closeVisible = this.isManualEnrollment_ &&
+          (step == STEP_SIGNIN || step == STEP_ERROR);
+      this.navigation_.refreshVisible =
+          !this.isManualEnrollment_ && step == STEP_SIGNIN;
+
       if (step == STEP_SIGNIN) {
         $('oauth-enroll-auth-view').focus();
       } else if (step == STEP_ERROR) {
diff --git a/chrome/browser/resources/chromeos/login/saml_confirm_password.css b/chrome/browser/resources/chromeos/login/saml_confirm_password.css
index 7185931..18b494c 100644
--- a/chrome/browser/resources/chromeos/login/saml_confirm_password.css
+++ b/chrome/browser/resources/chromeos/login/saml_confirm_password.css
@@ -8,19 +8,15 @@
   position: relative;
 }
 
-#closeButton {
+#navigation {
   color: white;
+  left: 0;
   position: absolute;
-  right: 10px;
-  top: 10px;
+  right: 0;
+  top: 0;
   z-index: 1;
 }
 
-:host-context(html[dir=rtl]) #closeButton {
-  left: 10px;
-  right: auto;
-}
-
 paper-dialog {
   --paper-dialog-title: {
     font-size: 15px;
diff --git a/chrome/browser/resources/chromeos/login/saml_confirm_password.html b/chrome/browser/resources/chromeos/login/saml_confirm_password.html
index 92bcf2e2..b7274a90 100644
--- a/chrome/browser/resources/chromeos/login/saml_confirm_password.html
+++ b/chrome/browser/resources/chromeos/login/saml_confirm_password.html
@@ -68,9 +68,9 @@
       </neon-animatable>
     </neon-animated-pages>
 
-    <gaia-icon-button id="closeButton" icon="close" on-tap="onClose_"
-        disabled="[[disabled]]" i18n-values="aria-label:closeButton">
-    </gaia-icon-button>
+    <navigation-bar id="navigation" close-visible on-close="onClose_"
+        disabled="[[disabled]]">
+    </navigation-bar>
 
     <paper-dialog id="cancelConfirmDlg" no-cancel-on-outside-click
         on-iron-overlay-closed="onDialogOverlayClosed_">
diff --git a/chrome/browser/resources/chromeos/login/saml_confirm_password.js b/chrome/browser/resources/chromeos/login/saml_confirm_password.js
index 5acc625..d596eea 100644
--- a/chrome/browser/resources/chromeos/login/saml_confirm_password.js
+++ b/chrome/browser/resources/chromeos/login/saml_confirm_password.js
@@ -30,7 +30,7 @@
   reset: function() {
     this.$.cancelConfirmDlg.close();
     this.disabled = false;
-    this.$.closeButton.hidden = false;
+    this.$.navigation.closeVisible = true;
     if (this.$.animatedPages.selected != 0)
       this.$.animatedPages.selected = 0;
     this.$.passwordInput.value = '';
@@ -59,7 +59,7 @@
     if (!this.$.passwordInput.checkValidity())
       return;
     this.$.animatedPages.selected = 1;
-    this.$.closeButton.hidden = true;
+    this.$.navigation.closeVisible = false;
     this.fire('passwordEnter', {password: this.$.passwordInput.value});
   },
 
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.css b/chrome/browser/resources/chromeos/login/screen_error_message.css
index 459b76a..f688f48c 100644
--- a/chrome/browser/resources/chromeos/login/screen_error_message.css
+++ b/chrome/browser/resources/chromeos/login/screen_error_message.css
@@ -140,15 +140,11 @@
   -webkit-animation: connecting-indicator-ellipsis 3s 1s infinite;
 }
 
-#error-close-button {
+#error-navigation {
   color: rgba(0, 0, 0, .54);
+  left: 0;
   position: absolute;
-  right: 10px;
-  top: 10px;
+  right: 0;
+  top: 0;
   z-index: 1;
 }
-
-html[dir=rtl] #error-close-button {
-  left: 10px;
-  right: auto;
-}
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.html b/chrome/browser/resources/chromeos/login/screen_error_message.html
index 827798e8..ec7fd9c 100644
--- a/chrome/browser/resources/chromeos/login/screen_error_message.html
+++ b/chrome/browser/resources/chromeos/login/screen_error_message.html
@@ -139,7 +139,5 @@
   <div class="error-controls">
     <div id="error-message-controls" class="step-controls"></div>
   </div>
-  <gaia-icon-button id="error-close-button" icon="close"
-      i18n-values="aria-label:closeButton">
-  </gaia-icon-button>
+  <navigation-bar id="error-navigation" close-visible><navigation-bar>
 </div>
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.js b/chrome/browser/resources/chromeos/login/screen_error_message.js
index fffdc6e8..969a1ff 100644
--- a/chrome/browser/resources/chromeos/login/screen_error_message.js
+++ b/chrome/browser/resources/chromeos/login/screen_error_message.js
@@ -96,7 +96,7 @@
     },
     set cancelable(value) {
       this.cancelable_ = value;
-      $('error-close-button').hidden = !value;
+      $('error-navigation').closeVisible = value;
     },
 
     /** @override */
@@ -128,7 +128,7 @@
       this.context.addObserver(CONTEXT_KEY_UI_STATE, function(ui_state) {
         self.setUIState(ui_state);
       });
-      $('error-close-button').addEventListener('click', this.cancel.bind(this));
+      $('error-navigation').addEventListener('close', this.cancel.bind(this));
     },
 
     /**
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
index 509b9a118..06a5616 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
@@ -13,55 +13,6 @@
   width: 562px;
 }
 
-#saml-info-container {
-  font-size: 12px;
-}
-
-#close-button-item,
-#back-button-item {
-  color: white;
-  position: absolute;
-  top: 10px;
-  z-index: 1;
-}
-
-#close-button-item[disabled],
-#back-button-item[disabled] {
-  color: rgb(127, 127, 127);
-}
-
-#close-button-item {
-  right: 10px;
-}
-
-#back-button-item {
-  left: 10px;
-}
-
-html[dir=rtl] #close-button-item {
-  left: 10px;
-  right: auto;
-}
-
-html[dir=rtl] #back-button-item {
-  -webkit-transform: scaleX(-1);
-  left: auto;
-  right: 10px;
-}
-
-.loading #close-button-item,
-.full-width #close-button-item {
-  color: rgba(0, 0, 0, .54);
-}
-
-.full-width #back-button-item {
-  display: none;
-}
-
-.loading.auth-completed #close-button-item {
-  display: none;
-}
-
 .signin-link {
   color: rgb(37, 79, 155);
   cursor: pointer;
@@ -77,6 +28,7 @@
 #gaia-signin-form-container,
 #signin-frame {
   height: 100%;
+  position: relative;
   width: 100%;
 }
 
@@ -140,3 +92,17 @@
   visibility: hidden;
 }
 
+#gaia-navigation {
+  color: white;
+  left: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+  z-index: 1;
+}
+
+.loading #gaia-navigation,
+.full-width #gaia-navigation {
+  color: rgba(0, 0, 0, .54);
+}
+
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.html b/chrome/browser/resources/chromeos/login/screen_gaia_signin.html
index a1a09d243..18afb7a 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.html
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.html
@@ -18,10 +18,5 @@
   <div id="saml-notice-container" hidden>
     <span id="saml-notice-message"></span>
   </div>
-  <gaia-icon-button id="back-button-item" icon="arrow-back" hidden
-      i18n-values="aria-label:backButton">
-  </gaia-icon-button>
-  <gaia-icon-button id="close-button-item" icon="close" hidden
-      i18n-values="aria-label:closeButton">
-  </gaia-icon-button>
+  <navigation-bar id="gaia-navigation"></navigation-bar>
 </div>
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
index cc5c9fd..4cc87f2 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -108,6 +108,7 @@
     },
     set cancelable(value) {
       this.cancelable_ = value;
+      $('login-header-bar').updateUI_();
     },
 
     /**
@@ -136,20 +137,38 @@
      */
     mostRecentUserActivity_: Date.now(),
 
+    /**
+     * An element containg navigation buttons.
+     */
+    navigation_: undefined,
+
     /** @override */
     decorate: function() {
-      $('offline-gaia').addEventListener('authCompleted',
-          this.onAuthCompletedMessage_.bind(this));
+      this.navigation_ = $('gaia-navigation');
 
       this.gaiaAuthHost_ = new cr.login.GaiaAuthHost($('signin-frame'));
       this.gaiaAuthHost_.addEventListener(
           'ready', this.onAuthReady_.bind(this));
-      this.gaiaAuthHost_.addEventListener(
-          'dialogShown', this.onDialogShown_.bind(this));
-      this.gaiaAuthHost_.addEventListener(
-          'dialogHidden', this.onDialogHidden_.bind(this));
-      this.gaiaAuthHost_.addEventListener(
-          'backButton', this.onBackButton_.bind(this));
+
+      var that = this;
+      [this.gaiaAuthHost_, $('offline-gaia')].forEach(function(frame) {
+        // Ignore events from currently inactive frame.
+        var localFilter = function(callback) {
+          return function(e) {
+            var isEventLocal = frame === $('offline-gaia');
+            if (isEventLocal === that.isLocal)
+              callback.call(that, e);
+          };
+        };
+
+        frame.addEventListener('authCompleted',
+                               localFilter(that.onAuthCompletedMessage_));
+        frame.addEventListener('backButton', localFilter(that.onBackButton_));
+        frame.addEventListener('dialogShown', localFilter(that.onDialogShown_));
+        frame.addEventListener('dialogHidden',
+                               localFilter(that.onDialogHidden_));
+      });
+
       this.gaiaAuthHost_.addEventListener(
           'showView', this.onShowView_.bind(this));
       this.gaiaAuthHost_.confirmPasswordCallback =
@@ -166,22 +185,19 @@
           this.onAuthDomainChange_.bind(this));
       this.gaiaAuthHost_.addEventListener('authFlowChange',
           this.onAuthFlowChange_.bind(this));
-      this.gaiaAuthHost_.addEventListener('authCompleted',
-          this.onAuthCompletedMessage_.bind(this));
+
       this.gaiaAuthHost_.addEventListener('loadAbort',
         this.onLoadAbortMessage_.bind(this));
       this.gaiaAuthHost_.addEventListener(
           'identifierEntered', this.onIdentifierEnteredMessage_.bind(this));
 
-      $('back-button-item').addEventListener('click', function(e) {
-        $('back-button-item').hidden = true;
-        $('signin-frame').back();
-        e.preventDefault();
-      });
+      this.navigation_.addEventListener('back', function() {
+        this.navigation_.backVisible = false;
+        this.getSigninFrame_().back();
+      }.bind(this));
 
-      $('close-button-item').addEventListener('click', function(e) {
+      this.navigation_.addEventListener('close', function() {
         this.cancel();
-        e.preventDefault();
       }.bind(this));
 
       $('gaia-whitelist-error').addEventListener('buttonclick', function() {
@@ -214,7 +230,7 @@
      * @param {boolean} value Whether local version of Gaia is used.
      */
     set isLocal(value) {
-      this.isLocal_ = value;
+      this.isLocal_ = !!value;
       $('signin-frame').hidden = this.isLocal_;
       $('offline-gaia').hidden = !this.isLocal_;
       chrome.send('updateOfflineLogin', [value]);
@@ -297,15 +313,9 @@
      */
     showLoadingUI_: function(show) {
       $('gaia-loading').hidden = !show;
-      if (this.isLocal) {
-        $('offline-gaia').hidden = show;
-      } else {
-        $('signin-frame').hidden = show;
-      }
+      this.getSigninFrame_().hidden = show;
       this.classList.toggle('loading', show);
       $('signin-frame').classList.remove('show');
-      if (!show)
-        this.classList.remove('auth-completed');
     },
 
     /**
@@ -402,9 +412,10 @@
       window.requestAnimationFrame(function() {
         chrome.send('loginVisible', ['gaia-loading']);
       });
-      $('back-button-item').disabled = false;
-      $('back-button-item').hidden = true;
-      $('close-button-item').disabled = false;
+
+      this.navigation_.disabled = false;
+      this.navigation_.backVisible = false;
+
       this.classList.toggle('loading', this.loading);
 
       // Button header is always visible when sign in is presented.
@@ -412,13 +423,17 @@
       Oobe.getInstance().headerHidden = false;
     },
 
-    onAfterShow: function(data) {
-      if (!this.loading) {
-        if (this.isLocal)
-          $('offline-gaia').focus();
-        else
-          $('signin-frame').focus();
-      }
+    getSigninFrame_: function() {
+      return this.isLocal ? $('offline-gaia') : $('signin-frame');
+    },
+
+    focusSigninFrame: function() {
+      this.getSigninFrame_().focus();
+    },
+
+    onAfterShow: function() {
+      if (!this.loading)
+        this.focusSigninFrame();
     },
 
     /**
@@ -517,7 +532,7 @@
     updateCancelButtonState: function() {
       this.cancelable = this.isLocal ||
                         (this.isShowUsers_ && $('pod-row').pods.length);
-      $('close-button-item').hidden = !this.cancelable;
+      this.navigation_.closeVisible = this.cancelable;
     },
 
     /**
@@ -539,17 +554,19 @@
 
     /**
      * Invoked when the authFlow property is changed on the GAIA host.
-     * @param {Event} e Property change event.
      */
-    onAuthFlowChange_: function(e) {
+    onAuthFlowChange_: function() {
       var isSAML = this.isSAML();
 
       this.classList.toggle('full-width', isSAML);
       $('saml-notice-container').hidden = !isSAML;
 
+      if (isSAML)
+        this.navigation_.backVisible = false;
+
       if (Oobe.getInstance().currentScreen === this) {
         Oobe.getInstance().updateScreenSize(this);
-        $('close-button-item').hidden = !(isSAML || this.cancelable);
+        this.navigation_.closeVisible = isSAML || this.cancelable;
       }
     },
 
@@ -572,8 +589,7 @@
      * @private
      */
     onDialogShown_: function() {
-      $('back-button-item').disabled = true;
-      $('close-button-item').disabled = true;
+      this.navigation_.disabled = true;
     },
 
     /**
@@ -581,8 +597,7 @@
      * @private
      */
     onDialogHidden_: function() {
-      $('back-button-item').disabled = false;
-      $('close-button-item').disabled = false;
+      this.navigation_.disabled = false;
     },
 
     /**
@@ -590,9 +605,9 @@
      * @private
      */
     onBackButton_: function(e) {
-      $('back-button-item').hidden = !e.detail;
+      this.navigation_.backVisible = !!e.detail;
       $('login-header-bar').updateUI_();
-      $('signin-frame').focus();
+      this.getSigninFrame_().focus();
     },
 
     /**
@@ -751,7 +766,10 @@
       }
 
       this.loading = true;
-      this.classList.add('auth-completed');
+
+      this.navigation_.backVisible = false;
+      this.navigation_.closeVisible = false;
+
       // Now that we're in logged in state header should be hidden.
       Oobe.getInstance().headerHidden = true;
       // Clear any error messages that were shown before login.
diff --git a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
index 30416a6..ed4f5246 100644
--- a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
+++ b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
@@ -550,15 +550,11 @@
   display: block;
 }
 
-#supervised-user-creation-close-button-item {
+#supervised-user-creation-navigation {
   color: rgba(0, 0, 0, .54);
+  left: 0;
   position: absolute;
-  right: 10px;
-  top: 10px;
+  right: 0;
+  top: 0;
   z-index: 1;
 }
-
-html[dir=rtl] #supervised-user-creation-close-button-item {
-  left: 10px;
-  right: auto;
-}
diff --git a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.html b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.html
index c9fddb52..04eec94 100644
--- a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.html
+++ b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.html
@@ -161,7 +161,6 @@
     <img class="import-pod-image"></img>
     <div class="import-pod-name"></div>
   </div>
-  <gaia-icon-button id="supervised-user-creation-close-button-item"
-      icon="close" i18n-values="aria-label:closeButton">
-  </gaia-icon-button>
+  <navigation-bar id="supervised-user-creation-navigation" close-visible>
+  </navigation-bar>
 </div>
diff --git a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
index 63183d3e5..a89c794 100644
--- a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
+++ b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.js
@@ -617,11 +617,8 @@
             previewElement.classList.remove('animation');
           });
 
-      $('supervised-user-creation-close-button-item').addEventListener(
-          'click', function(e) {
-            this.cancel();
-            e.preventDefault();
-          }.bind(this));
+      $('supervised-user-creation-navigation').addEventListener('close',
+          this.cancel.bind(this));
     },
 
     buttonIds: [],
@@ -1193,8 +1190,8 @@
             !this.importList_.selectedPod_ ||
             this.importList_.selectedPod_.user.exists;
       }
-      $('supervised-user-creation-close-button-item').hidden =
-          (visiblePage == 'created');
+      $('supervised-user-creation-navigation').closeVisible =
+          (visiblePage != 'created');
 
       chrome.send('currentSupervisedUserPage', [this.currentPage_]);
     },
diff --git a/chrome/browser/resources/md_downloads/crisper.js b/chrome/browser/resources/md_downloads/crisper.js
index 925699b..770c9fe 100644
--- a/chrome/browser/resources/md_downloads/crisper.js
+++ b/chrome/browser/resources/md_downloads/crisper.js
@@ -2,7 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-Polymer = {dom: 'shadow'};
+if (typeof Polymer == 'undefined')
+  Polymer = {dom: 'shadow'};
+else
+  console.error('Polymer is already defined.');
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// <include src="../../../../ui/webui/resources/js/i18n_template_no_process.js">
+
+i18nTemplate.process(document, loadTimeData);
 // 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.
@@ -1777,13 +1787,6 @@
 
 !function(a,b){b["true"]=a;var c={},d={},e={},f=null;!function(a){function b(a){if("number"==typeof a)return a;var b={};for(var c in a)b[c]=a[c];return b}function c(){this._delay=0,this._endDelay=0,this._fill="none",this._iterationStart=0,this._iterations=1,this._duration=0,this._playbackRate=1,this._direction="normal",this._easing="linear"}function d(b,d){var e=new c;return d&&(e.fill="both",e.duration="auto"),"number"!=typeof b||isNaN(b)?void 0!==b&&Object.getOwnPropertyNames(b).forEach(function(c){if("auto"!=b[c]){if(("number"==typeof e[c]||"duration"==c)&&("number"!=typeof b[c]||isNaN(b[c])))return;if("fill"==c&&-1==s.indexOf(b[c]))return;if("direction"==c&&-1==t.indexOf(b[c]))return;if("playbackRate"==c&&1!==b[c]&&a.isDeprecated("AnimationEffectTiming.playbackRate","2014-11-28","Use Animation.playbackRate instead."))return;e[c]=b[c]}}):e.duration=b,e}function e(a){return"number"==typeof a&&(a=isNaN(a)?{duration:0}:{duration:a}),a}function f(b,c){b=a.numericTimingToObject(b);var e=d(b,c);return e._easing=i(e.easing),e}function g(a,b,c,d){return 0>a||a>1||0>c||c>1?B:function(e){function f(a,b,c){return 3*a*(1-c)*(1-c)*c+3*b*(1-c)*c*c+c*c*c}if(0==e||1==e)return e;for(var g=0,h=1;;){var i=(g+h)/2,j=f(a,c,i);if(Math.abs(e-j)<.001)return f(b,d,i);e>j?g=i:h=i}}}function h(a,b){return function(c){if(c>=1)return 1;var d=1/a;return c+=b*d,c-c%d}}function i(a){var b=z.exec(a);if(b)return g.apply(this,b.slice(1).map(Number));var c=A.exec(a);if(c)return h(Number(c[1]),{start:u,middle:v,end:w}[c[2]]);var d=x[a];return d?d:B}function j(a){return Math.abs(k(a)/a.playbackRate)}function k(a){return a.duration*a.iterations}function l(a,b,c){return null==b?C:b<c.delay?D:b>=c.delay+a?E:F}function m(a,b,c,d,e){switch(d){case D:return"backwards"==b||"both"==b?0:null;case F:return c-e;case E:return"forwards"==b||"both"==b?a:null;case C:return null}}function n(a,b,c,d){return(d.playbackRate<0?b-a:b)*d.playbackRate+c}function o(a,b,c,d,e){return 1/0===c||c===-1/0||c-d==b&&e.iterations&&(e.iterations+e.iterationStart)%1==0?a:c%a}function p(a,b,c,d){return 0===c?0:b==a?d.iterationStart+d.iterations-1:Math.floor(c/a)}function q(a,b,c,d){var e=a%2>=1,f="normal"==d.direction||d.direction==(e?"alternate-reverse":"alternate"),g=f?c:b-c,h=g/b;return b*d.easing(h)}function r(a,b,c){var d=l(a,b,c),e=m(a,c.fill,b,d,c.delay);if(null===e)return null;if(0===a)return d===D?0:1;var f=c.iterationStart*c.duration,g=n(a,e,f,c),h=o(c.duration,k(c),g,f,c),i=p(c.duration,h,g,c);return q(i,c.duration,h,c)/c.duration}var s="backwards|forwards|both|none".split("|"),t="reverse|alternate|alternate-reverse".split("|");c.prototype={_setMember:function(b,c){this["_"+b]=c,this._effect&&(this._effect._timingInput[b]=c,this._effect._timing=a.normalizeTimingInput(a.normalizeTimingInput(this._effect._timingInput)),this._effect.activeDuration=a.calculateActiveDuration(this._effect._timing),this._effect._animation&&this._effect._animation._rebuildUnderlyingAnimation())},get playbackRate(){return this._playbackRate},set delay(a){this._setMember("delay",a)},get delay(){return this._delay},set endDelay(a){this._setMember("endDelay",a)},get endDelay(){return this._endDelay},set fill(a){this._setMember("fill",a)},get fill(){return this._fill},set iterationStart(a){this._setMember("iterationStart",a)},get iterationStart(){return this._iterationStart},set duration(a){this._setMember("duration",a)},get duration(){return this._duration},set direction(a){this._setMember("direction",a)},get direction(){return this._direction},set easing(a){this._setMember("easing",a)},get easing(){return this._easing},set iterations(a){this._setMember("iterations",a)},get iterations(){return this._iterations}};var u=1,v=.5,w=0,x={ease:g(.25,.1,.25,1),"ease-in":g(.42,0,1,1),"ease-out":g(0,0,.58,1),"ease-in-out":g(.42,0,.58,1),"step-start":h(1,u),"step-middle":h(1,v),"step-end":h(1,w)},y="\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*",z=new RegExp("cubic-bezier\\("+y+","+y+","+y+","+y+"\\)"),A=/steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/,B=function(a){return a},C=0,D=1,E=2,F=3;a.cloneTimingInput=b,a.makeTiming=d,a.numericTimingToObject=e,a.normalizeTimingInput=f,a.calculateActiveDuration=j,a.calculateTimeFraction=r,a.calculatePhase=l,a.toTimingFunction=i}(c,f),function(a){function b(a,b){return a in h?h[a][b]||b:b}function c(a,c,d){var g=e[a];if(g){f.style[a]=c;for(var h in g){var i=g[h],j=f.style[i];d[i]=b(i,j)}}else d[a]=b(a,c)}function d(b){function d(){var a=e.length;null==e[a-1].offset&&(e[a-1].offset=1),a>1&&null==e[0].offset&&(e[0].offset=0);for(var b=0,c=e[0].offset,d=1;a>d;d++){var f=e[d].offset;if(null!=f){for(var g=1;d-b>g;g++)e[b+g].offset=c+(f-c)*g/(d-b);b=d,c=f}}}if(!Array.isArray(b)&&null!==b)throw new TypeError("Keyframes must be null or an array of keyframes");if(null==b)return[];for(var e=b.map(function(b){var d={};for(var e in b){var f=b[e];if("offset"==e){if(null!=f&&(f=Number(f),!isFinite(f)))throw new TypeError("keyframe offsets must be numbers.")}else{if("composite"==e)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"add compositing is not supported"};f="easing"==e?a.toTimingFunction(f):""+f}c(e,f,d)}return void 0==d.offset&&(d.offset=null),void 0==d.easing&&(d.easing=a.toTimingFunction("linear")),d}),f=!0,g=-1/0,h=0;h<e.length;h++){var i=e[h].offset;if(null!=i){if(g>i)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:"InvalidModificationError",message:"Keyframes are not loosely sorted by offset. Sort or specify offsets."};g=i}else f=!1}return e=e.filter(function(a){return a.offset>=0&&a.offset<=1}),f||d(),e}var e={background:["backgroundImage","backgroundPosition","backgroundSize","backgroundRepeat","backgroundAttachment","backgroundOrigin","backgroundClip","backgroundColor"],border:["borderTopColor","borderTopStyle","borderTopWidth","borderRightColor","borderRightStyle","borderRightWidth","borderBottomColor","borderBottomStyle","borderBottomWidth","borderLeftColor","borderLeftStyle","borderLeftWidth"],borderBottom:["borderBottomWidth","borderBottomStyle","borderBottomColor"],borderColor:["borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],borderLeft:["borderLeftWidth","borderLeftStyle","borderLeftColor"],borderRadius:["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],borderRight:["borderRightWidth","borderRightStyle","borderRightColor"],borderTop:["borderTopWidth","borderTopStyle","borderTopColor"],borderWidth:["borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],flex:["flexGrow","flexShrink","flexBasis"],font:["fontFamily","fontSize","fontStyle","fontVariant","fontWeight","lineHeight"],margin:["marginTop","marginRight","marginBottom","marginLeft"],outline:["outlineColor","outlineStyle","outlineWidth"],padding:["paddingTop","paddingRight","paddingBottom","paddingLeft"]},f=document.createElementNS("http://www.w3.org/1999/xhtml","div"),g={thin:"1px",medium:"3px",thick:"5px"},h={borderBottomWidth:g,borderLeftWidth:g,borderRightWidth:g,borderTopWidth:g,fontSize:{"xx-small":"60%","x-small":"75%",small:"89%",medium:"100%",large:"120%","x-large":"150%","xx-large":"200%"},fontWeight:{normal:"400",bold:"700"},outlineWidth:g,textShadow:{none:"0px 0px 0px transparent"},boxShadow:{none:"0px 0px 0px 0px transparent"}};a.normalizeKeyframes=d}(c,f),function(a){var b={};a.isDeprecated=function(a,c,d,e){var f=e?"are":"is",g=new Date,h=new Date(c);return h.setMonth(h.getMonth()+3),h>g?(a in b||console.warn("Web Animations: "+a+" "+f+" deprecated and will stop working on "+h.toDateString()+". "+d),b[a]=!0,!1):!0},a.deprecated=function(b,c,d,e){var f=e?"are":"is";if(a.isDeprecated(b,c,d,e))throw new Error(b+" "+f+" no longer supported. "+d)}}(c),function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,"play|currentTime|pause|reverse|playbackRate|cancel|finish|startTime|playState".split("|").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}!function(a,b){function c(a){for(var b={},c=0;c<a.length;c++)for(var d in a[c])if("offset"!=d&&"easing"!=d&&"composite"!=d){var e={offset:a[c].offset,easing:a[c].easing,value:a[c][d]};b[d]=b[d]||[],b[d].push(e)}for(var f in b){var g=b[f];if(0!=g[0].offset||1!=g[g.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"Partial keyframes are not supported"}}return b}function d(a){var c=[];for(var d in a)for(var e=a[d],f=0;f<e.length-1;f++){var g=e[f].offset,h=e[f+1].offset,i=e[f].value,j=e[f+1].value;g==h&&(1==h?i=j:j=i),c.push({startTime:g,endTime:h,easing:e[f].easing,property:d,interpolation:b.propertyInterpolation(d,i,j)})}return c.sort(function(a,b){return a.startTime-b.startTime}),c}b.convertEffectInput=function(e){var f=a.normalizeKeyframes(e),g=c(f),h=d(g);return function(a,c){if(null!=c)h.filter(function(a){return 0>=c&&0==a.startTime||c>=1&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(d){var e=c-d.startTime,f=d.endTime-d.startTime,g=0==f?0:d.easing(e/f);b.apply(a,d.property,d.interpolation(g))});else for(var d in g)"offset"!=d&&"easing"!=d&&"composite"!=d&&b.clear(a,d)}}}(c,d,f),function(a){function b(a,b,c){e[c]=e[c]||[],e[c].push([a,b])}function c(a,c,d){for(var e=0;e<d.length;e++){var f=d[e];b(a,c,f),/-/.test(f)&&b(a,c,f.replace(/-(.)/g,function(a,b){return b.toUpperCase()}))}}function d(b,c,d){if("initial"==c||"initial"==d){var g=b.replace(/-(.)/g,function(a,b){return b.toUpperCase()});"initial"==c&&(c=f[g]),"initial"==d&&(d=f[g])}for(var h=c==d?[]:e[b],i=0;h&&i<h.length;i++){var j=h[i][0](c),k=h[i][0](d);if(void 0!==j&&void 0!==k){var l=h[i][1](j,k);if(l){var m=a.Interpolation.apply(null,l);return function(a){return 0==a?c:1==a?d:m(a)}}}}return a.Interpolation(!1,!0,function(a){return a?d:c})}var e={};a.addPropertiesHandler=c;var f={backgroundColor:"transparent",backgroundPosition:"0% 0%",borderBottomColor:"currentColor",borderBottomLeftRadius:"0px",borderBottomRightRadius:"0px",borderBottomWidth:"3px",borderLeftColor:"currentColor",borderLeftWidth:"3px",borderRightColor:"currentColor",borderRightWidth:"3px",borderSpacing:"2px",borderTopColor:"currentColor",borderTopLeftRadius:"0px",borderTopRightRadius:"0px",borderTopWidth:"3px",bottom:"auto",clip:"rect(0px, 0px, 0px, 0px)",color:"black",fontSize:"100%",fontWeight:"400",height:"auto",left:"auto",letterSpacing:"normal",lineHeight:"120%",marginBottom:"0px",marginLeft:"0px",marginRight:"0px",marginTop:"0px",maxHeight:"none",maxWidth:"none",minHeight:"0px",minWidth:"0px",opacity:"1.0",outlineColor:"invert",outlineOffset:"0px",outlineWidth:"3px",paddingBottom:"0px",paddingLeft:"0px",paddingRight:"0px",paddingTop:"0px",right:"auto",textIndent:"0px",textShadow:"0px 0px 0px transparent",top:"auto",transform:"",verticalAlign:"0px",visibility:"visible",width:"auto",wordSpacing:"normal",zIndex:"auto"};a.propertyInterpolation=d}(d,f),function(a,b){function c(b){var c=a.calculateActiveDuration(b),d=function(d){return a.calculateTimeFraction(c,d,b)};return d._totalDuration=b.delay+c+b.endDelay,d._isCurrent=function(d){var e=a.calculatePhase(c,d,b);return e===PhaseActive||e===PhaseBefore},d}b.KeyframeEffect=function(d,e,f){var g,h=c(a.normalizeTimingInput(f)),i=b.convertEffectInput(e),j=function(){i(d,g)};return j._update=function(a){return g=h(a),null!==g},j._clear=function(){i(d,null)},j._hasSameTarget=function(a){return d===a},j._isCurrent=h._isCurrent,j._totalDuration=h._totalDuration,j},b.NullEffect=function(a){var b=function(){a&&(a(),a=null)};return b._update=function(){return null},b._totalDuration=0,b._isCurrent=function(){return!1},b._hasSameTarget=function(){return!1},b}}(c,d,f),function(a){a.apply=function(b,c,d){b.style[a.propertyName(c)]=d},a.clear=function(b,c){b.style[a.propertyName(c)]=""}}(d,f),function(a){window.Element.prototype.animate=function(b,c){return a.timeline._play(a.KeyframeEffect(this,b,c))}}(d),function(a){function b(a,c,d){if("number"==typeof a&&"number"==typeof c)return a*(1-d)+c*d;if("boolean"==typeof a&&"boolean"==typeof c)return.5>d?a:c;if(a.length==c.length){for(var e=[],f=0;f<a.length;f++)e.push(b(a[f],c[f],d));return e}throw"Mismatched interpolation arguments "+a+":"+c}a.Interpolation=function(a,c,d){return function(e){return d(b(a,c,e))}}}(d,f),function(a,b){a.sequenceNumber=0;var c=function(a,b,c){this.target=a,this.currentTime=b,this.timelineTime=c,this.type="finish",this.bubbles=!1,this.cancelable=!1,this.currentTarget=a,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()};b.Animation=function(b){this._sequenceNumber=a.sequenceNumber++,this._currentTime=0,this._startTime=null,this._paused=!1,this._playbackRate=1,this._inTimeline=!0,this._finishedFlag=!1,this.onfinish=null,this._finishHandlers=[],this._effect=b,this._inEffect=this._effect._update(0),this._idle=!0,this._currentTimePending=!1},b.Animation.prototype={_ensureAlive:function(){this._inEffect=this._effect._update(this.playbackRate<0&&0===this.currentTime?-1:this.currentTime),this._inTimeline||!this._inEffect&&this._finishedFlag||(this._inTimeline=!0,b.timeline._animations.push(this))},_tickCurrentTime:function(a,b){a!=this._currentTime&&(this._currentTime=a,this._isFinished&&!b&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this._ensureAlive())},get currentTime(){return this._idle||this._currentTimePending?null:this._currentTime},set currentTime(a){a=+a,isNaN(a)||(b.restart(),this._paused||null==this._startTime||(this._startTime=this._timeline.currentTime-a/this._playbackRate),this._currentTimePending=!1,this._currentTime!=a&&(this._tickCurrentTime(a,!0),b.invalidateEffects()))},get startTime(){return this._startTime},set startTime(a){a=+a,isNaN(a)||this._paused||this._idle||(this._startTime=a,this._tickCurrentTime((this._timeline.currentTime-this._startTime)*this.playbackRate),b.invalidateEffects())},get playbackRate(){return this._playbackRate},set playbackRate(a){if(a!=this._playbackRate){var b=this.currentTime;this._playbackRate=a,this._startTime=null,"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!=b&&(this.currentTime=b)}},get _isFinished(){return!this._idle&&(this._playbackRate>0&&this._currentTime>=this._totalDuration||this._playbackRate<0&&this._currentTime<=0)},get _totalDuration(){return this._effect._totalDuration},get playState(){return this._idle?"idle":null==this._startTime&&!this._paused&&0!=this.playbackRate||this._currentTimePending?"pending":this._paused?"paused":this._isFinished?"finished":"running"},play:function(){this._paused=!1,(this._isFinished||this._idle)&&(this._currentTime=this._playbackRate>0?0:this._totalDuration,this._startTime=null,b.invalidateEffects()),this._finishedFlag=!1,b.restart(),this._idle=!1,this._ensureAlive()},pause:function(){this._isFinished||this._paused||this._idle||(this._currentTimePending=!0),this._startTime=null,this._paused=!0},finish:function(){this._idle||(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this._currentTimePending=!1)},cancel:function(){this._inEffect&&(this._inEffect=!1,this._idle=!0,this.currentTime=0,this._startTime=null,this._effect._update(null),b.invalidateEffects(),b.restart())},reverse:function(){this.playbackRate*=-1,this.play()},addEventListener:function(a,b){"function"==typeof b&&"finish"==a&&this._finishHandlers.push(b)},removeEventListener:function(a,b){if("finish"==a){var c=this._finishHandlers.indexOf(b);c>=0&&this._finishHandlers.splice(c,1)}},_fireEvents:function(a){var b=this._isFinished;if((b||this._idle)&&!this._finishedFlag){var d=new c(this,this._currentTime,a),e=this._finishHandlers.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){e.forEach(function(a){a.call(d.target,d)})},0)}this._finishedFlag=b},_tick:function(a){return this._idle||this._paused||(null==this._startTime?this.startTime=a-this._currentTime/this.playbackRate:this._isFinished||this._tickCurrentTime((a-this._startTime)*this.playbackRate)),this._currentTimePending=!1,this._fireEvents(a),!this._idle&&(this._inEffect||!this._finishedFlag)}}}(c,d,f),function(a,b){function c(a){var b=i;i=[],a<s.currentTime&&(a=s.currentTime),g(a),b.forEach(function(b){b[1](a)}),o&&g(a),f(),l=void 0}function d(a,b){return a._sequenceNumber-b._sequenceNumber}function e(){this._animations=[],this.currentTime=window.performance&&performance.now?performance.now():0}function f(){p.forEach(function(a){a()}),p.length=0}function g(a){n=!1;var c=b.timeline;c.currentTime=a,c._animations.sort(d),m=!1;var e=c._animations;c._animations=[];var f=[],g=[];e=e.filter(function(b){return b._inTimeline=b._tick(a),b._inEffect?g.push(b._effect):f.push(b._effect),b._isFinished||b._paused||b._idle||(m=!0),b._inTimeline}),p.push.apply(p,f),p.push.apply(p,g),c._animations.push.apply(c._animations,e),o=!1,m&&requestAnimationFrame(function(){})}var h=window.requestAnimationFrame,i=[],j=0;window.requestAnimationFrame=function(a){var b=j++;return 0==i.length&&h(c),i.push([b,a]),b},window.cancelAnimationFrame=function(a){i.forEach(function(b){b[0]==a&&(b[1]=function(){})})},e.prototype={_play:function(c){c._timing=a.normalizeTimingInput(c.timing);var d=new b.Animation(c);return d._idle=!1,d._timeline=this,this._animations.push(d),b.restart(),b.invalidateEffects(),d}};var k,l=void 0,k=function(){return void 0==l&&(l=performance.now()),l},m=!1,n=!1;b.restart=function(){return m||(m=!0,requestAnimationFrame(function(){}),n=!0),n};var o=!1;b.invalidateEffects=function(){o=!0};var p=[],q=1e3/60,r=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){if(o){var a=k();a-s.currentTime>0&&(s.currentTime+=q*(Math.floor((a-s.currentTime)/q)+1)),g(s.currentTime)}return f(),r.apply(this,arguments)}});var s=new e;b.timeline=s}(c,d,f),function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\s*/,"");var c=a(b);return c?[c[0],c[1].replace(/^\s*/,"")]:void 0}function d(a,d,e){a=c.bind(null,a);for(var f=[];;){var g=a(e);if(!g)return[f,e];if(f.push(g[0]),e=g[1],g=b(d,e),!g||""==g[1])return[f,e];e=g[1]}}function e(a,b){for(var c=0,d=0;d<b.length&&(!/\s|,/.test(b[d])||0!=c);d++)if("("==b[d])c++;else if(")"==b[d]&&(c--,0==c&&d++,0>=c))break;var e=a(b.substr(0,d));return void 0==e?void 0:[e,b.substr(d)]}function f(a,b){for(var c=a,d=b;c&&d;)c>d?c%=d:d%=c;return c=a*b/(c+d)}function g(a){return function(b){var c=a(b);return c&&(c[0]=void 0),c}}function h(a,b){return function(c){var d=a(c);return d?d:[b,c]}}function i(b,c){for(var d=[],e=0;e<b.length;e++){var f=a.consumeTrimmed(b[e],c);if(!f||""==f[0])return;void 0!==f[0]&&d.push(f[0]),c=f[1]}return""==c?d:void 0}function j(a,b,c,d,e){for(var g=[],h=[],i=[],j=f(d.length,e.length),k=0;j>k;k++){var l=b(d[k%d.length],e[k%e.length]);if(!l)return;g.push(l[0]),h.push(l[1]),i.push(l[2])}return[g,h,function(b){var d=b.map(function(a,b){return i[b](a)}).join(c);return a?a(d):d}]}function k(a,b,c){for(var d=[],e=[],f=[],g=0,h=0;h<c.length;h++)if("function"==typeof c[h]){var i=c[h](a[g],b[g++]);d.push(i[0]),e.push(i[1]),f.push(i[2])}else!function(a){d.push(!1),e.push(!1),f.push(function(){return c[a]})}(h);return[d,e,function(a){for(var b="",c=0;c<a.length;c++)b+=f[c](a[c]);return b}]}a.consumeToken=b,a.consumeTrimmed=c,a.consumeRepeated=d,a.consumeParenthesised=e,a.ignore=g,a.optional=h,a.consumeList=i,a.mergeNestedRepeated=j.bind(null,null),a.mergeWrappedNestedRepeated=j,a.mergeList=k}(d),function(a){function b(b){function c(b){var c=a.consumeToken(/^inset/i,b);if(c)return d.inset=!0,c;var c=a.consumeLengthOrPercent(b);if(c)return d.lengths.push(c[0]),c;var c=a.consumeColor(b);return c?(d.color=c[0],c):void 0}var d={inset:!1,lengths:[],color:null},e=a.consumeRepeated(c,/^/,b);return e&&e[0].length?[d,e[1]]:void 0}function c(c){var d=a.consumeRepeated(b,/^,/,c);return d&&""==d[1]?d[0]:void 0}function d(b,c){for(;b.lengths.length<Math.max(b.lengths.length,c.lengths.length);)b.lengths.push({px:0});for(;c.lengths.length<Math.max(b.lengths.length,c.lengths.length);)c.lengths.push({px:0});if(b.inset==c.inset&&!!b.color==!!c.color){for(var d,e=[],f=[[],0],g=[[],0],h=0;h<b.lengths.length;h++){var i=a.mergeDimensions(b.lengths[h],c.lengths[h],2==h);f[0].push(i[0]),g[0].push(i[1]),e.push(i[2])}if(b.color&&c.color){var j=a.mergeColors(b.color,c.color);f[1]=j[0],g[1]=j[1],d=j[2]}return[f,g,function(a){for(var c=b.inset?"inset ":" ",f=0;f<e.length;f++)c+=e[f](a[0][f])+" ";return d&&(c+=d(a[1])),c}]}}function e(b,c,d,e){function f(a){return{inset:a,color:[0,0,0,0],lengths:[{px:0},{px:0},{px:0},{px:0}]}}for(var g=[],h=[],i=0;i<d.length||i<e.length;i++){var j=d[i]||f(e[i].inset),k=e[i]||f(d[i].inset);g.push(j),h.push(k)}return a.mergeNestedRepeated(b,c,g,h)}var f=e.bind(null,d,", ");a.addPropertiesHandler(c,f,["box-shadow","text-shadow"])}(d),function(a){function b(a){return a.toFixed(3).replace(".000","")}function c(a,b,c){return Math.min(b,Math.max(a,c))}function d(a){return/^\s*[-+]?(\d*\.)?\d+\s*$/.test(a)?Number(a):void 0}function e(a,c){return[a,c,b]}function f(a,b){return 0!=a?h(0,1/0)(a,b):void 0}function g(a,b){return[a,b,function(a){return Math.round(c(1,1/0,a))}]}function h(a,d){return function(e,f){return[e,f,function(e){return b(c(a,d,e))}]}}function i(a,b){return[a,b,Math.round]}a.clamp=c,a.addPropertiesHandler(d,h(0,1/0),["border-image-width","line-height"]),a.addPropertiesHandler(d,h(0,1),["opacity","shape-image-threshold"]),a.addPropertiesHandler(d,f,["flex-grow","flex-shrink"]),a.addPropertiesHandler(d,g,["orphans","widows"]),a.addPropertiesHandler(d,i,["z-index"]),a.parseNumber=d,a.mergeNumbers=e,a.numberToString=b}(d,f),function(a){function b(a,b){return"visible"==a||"visible"==b?[0,1,function(c){return 0>=c?a:c>=1?b:"visible"}]:void 0}a.addPropertiesHandler(String,b,["visibility"])}(d),function(a){function b(a){a=a.trim(),e.fillStyle="#000",e.fillStyle=a;var b=e.fillStyle;if(e.fillStyle="#fff",e.fillStyle=a,b==e.fillStyle){e.fillRect(0,0,1,1);var c=e.getImageData(0,0,1,1).data;e.clearRect(0,0,1,1);var d=c[3]/255;return[c[0]*d,c[1]*d,c[2]*d,d]}}function c(b,c){return[b,c,function(b){function c(a){return Math.max(0,Math.min(255,a))}if(b[3])for(var d=0;3>d;d++)b[d]=Math.round(c(b[d]/b[3]));return b[3]=a.numberToString(a.clamp(0,1,b[3])),"rgba("+b.join(",")+")"}]}var d=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");d.width=d.height=1;var e=d.getContext("2d");a.addPropertiesHandler(b,c,["background-color","border-bottom-color","border-left-color","border-right-color","border-top-color","color","outline-color","text-decoration-color"]),a.consumeColor=a.consumeParenthesised.bind(null,b),a.mergeColors=c}(d,f),function(a,b){function c(a,b){if(b=b.trim().toLowerCase(),"0"==b&&"px".search(a)>=0)return{px:0};if(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\(/g,"(");var c={};b=b.replace(a,function(a){return c[a]=null,"U"+a});for(var d="U("+a.source+")",e=b.replace(/[-+]?(\d*\.)?\d+/g,"N").replace(new RegExp("N"+d,"g"),"D").replace(/\s[+-]\s/g,"O").replace(/\s/g,""),f=[/N\*(D)/g,/(N|D)[*/]N/g,/(N|D)O\1/g,/\((N|D)\)/g],g=0;g<f.length;)f[g].test(e)?(e=e.replace(f[g],"$1"),g=0):g++;if("D"==e){for(var h in c){var i=eval(b.replace(new RegExp("U"+h,"g"),"").replace(new RegExp(d,"g"),"*0"));if(!isFinite(i))return;c[h]=i}return c}}}function d(a,b){return e(a,b,!0)}function e(b,c,d){var e,f=[];for(e in b)f.push(e);for(e in c)f.indexOf(e)<0&&f.push(e);return b=f.map(function(a){return b[a]||0}),c=f.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,e){return 1==b.length&&d&&(c=Math.max(c,0)),a.numberToString(c)+f[e]}).join(" + ");return b.length>1?"calc("+c+")":c}]}var f="px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc",g=c.bind(null,new RegExp(f,"g")),h=c.bind(null,new RegExp(f+"|%","g")),i=c.bind(null,/deg|rad|grad|turn/g);a.parseLength=g,a.parseLengthOrPercent=h,a.consumeLengthOrPercent=a.consumeParenthesised.bind(null,h),a.parseAngle=i,a.mergeDimensions=e;var j=a.consumeParenthesised.bind(null,g),k=a.consumeRepeated.bind(void 0,j,/^/),l=a.consumeRepeated.bind(void 0,k,/^,/);a.consumeSizePairList=l;var m=function(a){var b=l(a);return b&&""==b[1]?b[0]:void 0},n=a.mergeNestedRepeated.bind(void 0,d," "),o=a.mergeNestedRepeated.bind(void 0,n,",");a.mergeNonNegativeSizePair=n,a.addPropertiesHandler(m,o,["background-size"]),a.addPropertiesHandler(h,d,["border-bottom-width","border-image-width","border-left-width","border-right-width","border-top-width","flex-basis","font-size","height","line-height","max-height","max-width","outline-width","width"]),a.addPropertiesHandler(h,e,["border-bottom-left-radius","border-bottom-right-radius","border-top-left-radius","border-top-right-radius","bottom","left","letter-spacing","margin-bottom","margin-left","margin-right","margin-top","min-height","min-width","outline-offset","padding-bottom","padding-left","padding-right","padding-top","perspective","right","shape-margin","text-indent","top","vertical-align","word-spacing"])}(d,f),function(a){function b(b){return a.consumeLengthOrPercent(b)||a.consumeToken(/^auto/,b)}function c(c){var d=a.consumeList([a.ignore(a.consumeToken.bind(null,/^rect/)),a.ignore(a.consumeToken.bind(null,/^\(/)),a.consumeRepeated.bind(null,b,/^,/),a.ignore(a.consumeToken.bind(null,/^\)/))],c);return d&&4==d[0].length?d[0]:void 0}function d(b,c){return"auto"==b||"auto"==c?[!0,!1,function(d){var e=d?b:c;if("auto"==e)return"auto";var f=a.mergeDimensions(e,e);return f[2](f[0])}]:a.mergeDimensions(b,c)}function e(a){return"rect("+a+")"}var f=a.mergeWrappedNestedRepeated.bind(null,e,d,", ");a.parseBox=c,a.mergeBoxes=f,a.addPropertiesHandler(c,f,["clip"])}(d,f),function(a){function b(a){return function(b){var c=0;return a.map(function(a){return a===j?b[c++]:a})}}function c(a){return a}function d(b){if(b=b.toLowerCase().trim(),"none"==b)return[];for(var c,d=/\s*(\w+)\(([^)]*)\)/g,e=[],f=0;c=d.exec(b);){if(c.index!=f)return;f=c.index+c[0].length;var g=c[1],h=m[g];if(!h)return;var i=c[2].split(","),j=h[0];if(j.length<i.length)return;for(var n=[],o=0;o<j.length;o++){var p,q=i[o],r=j[o];if(p=q?{A:function(b){return"0"==b.trim()?l:a.parseAngle(b)},N:a.parseNumber,T:a.parseLengthOrPercent,L:a.parseLength}[r.toUpperCase()](q):{a:l,n:n[0],t:k}[r],void 0===p)return;n.push(p)}if(e.push({t:g,d:n}),d.lastIndex==b.length)return e}}function e(a){return a.toFixed(6).replace(".000000","")}function f(b,c){if(b.decompositionPair!==c){b.decompositionPair=c;var d=a.makeMatrixDecomposition(b)}if(c.decompositionPair!==b){c.decompositionPair=b;var f=a.makeMatrixDecomposition(c)}return null==d[0]||null==f[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(d[0].push(0),f[0].push(1),[d,f,function(b){var c=a.quat(d[0][3],f[0][3],b[5]),g=a.composeMatrix(b[0],b[1],b[2],c,b[4]),h=g.map(e).join(",");return h}])}function g(a){return a.replace(/[xy]/,"")}function h(a){return a.replace(/(x|y|z|3d)?$/,"3d")}function i(b,c){var d=a.makeMatrixDecomposition&&!0,e=!1;if(!b.length||!c.length){b.length||(e=!0,b=c,c=[]);for(var i=0;i<b.length;i++){var j=b[i].t,k=b[i].d,l="scale"==j.substr(0,5)?1:0;c.push({t:j,d:k.map(function(a){if("number"==typeof a)return l;var b={};for(var c in a)b[c]=l;return b})})}}var n=function(a,b){return"perspective"==a&&"perspective"==b||("matrix"==a||"matrix3d"==a)&&("matrix"==b||"matrix3d"==b)},o=[],p=[],q=[];if(b.length!=c.length){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]]}else for(var i=0;i<b.length;i++){var j,s=b[i].t,t=c[i].t,u=b[i].d,v=c[i].d,w=m[s],x=m[t];if(n(s,t)){if(!d)return;var r=f([b[i]],[c[i]]);o.push(r[0]),p.push(r[1]),q.push(["matrix",[r[2]]])}else{if(s==t)j=s;else if(w[2]&&x[2]&&g(s)==g(t))j=g(s),u=w[2](u),v=x[2](v);else{if(!w[1]||!x[1]||h(s)!=h(t)){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]];break}j=h(s),u=w[1](u),v=x[1](v)}for(var y=[],z=[],A=[],B=0;B<u.length;B++){var C="number"==typeof u[B]?a.mergeNumbers:a.mergeDimensions,r=C(u[B],v[B]);y[B]=r[0],z[B]=r[1],A.push(r[2])}o.push(y),p.push(z),q.push([j,A])}}if(e){var D=o;o=p,p=D}return[o,p,function(a){return a.map(function(a,b){var c=a.map(function(a,c){return q[b][1][c](a)}).join(",");return"matrix"==q[b][0]&&16==c.split(",").length&&(q[b][0]="matrix3d"),q[b][0]+"("+c+")"}).join(" ")}]}var j=null,k={px:0},l={deg:0},m={matrix:["NNNNNN",[j,j,0,0,j,j,0,0,0,0,1,0,j,j,0,1],c],matrix3d:["NNNNNNNNNNNNNNNN",c],rotate:["A"],rotatex:["A"],rotatey:["A"],rotatez:["A"],rotate3d:["NNNA"],perspective:["L"],scale:["Nn",b([j,j,1]),c],scalex:["N",b([j,1,1]),b([j,1])],scaley:["N",b([1,j,1]),b([1,j])],scalez:["N",b([1,1,j])],scale3d:["NNN",c],skew:["Aa",null,c],skewx:["A",null,b([j,l])],skewy:["A",null,b([l,j])],translate:["Tt",b([j,j,k]),c],translatex:["T",b([j,k,k]),b([j,k])],translatey:["T",b([k,j,k]),b([k,j])],translatez:["L",b([k,k,j])],translate3d:["TTL",c]};a.addPropertiesHandler(d,i,["transform"])}(d,f),function(a){function b(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(c[a]=b)})}var c={};b("transform",["webkitTransform","msTransform"]),b("transformOrigin",["webkitTransformOrigin"]),b("perspective",["webkitPerspective"]),b("perspectiveOrigin",["webkitPerspectiveOrigin"]),a.propertyName=function(a){return c[a]||a}}(d,f)}(),!function(a,b){function c(a){var b=window.document.timeline;b.currentTime=a,b._discardAnimations(),0==b._animations.length?e=!1:requestAnimationFrame(c)}var d=window.requestAnimationFrame;window.requestAnimationFrame=function(a){return d(function(b){window.document.timeline._updateAnimationsPromises(),a(b),window.document.timeline._updateAnimationsPromises()})},b.AnimationTimeline=function(){this._animations=[],this.currentTime=void 0},b.AnimationTimeline.prototype={getAnimations:function(){return this._discardAnimations(),this._animations.slice()},_updateAnimationsPromises:function(){b.animationsWithPromises=b.animationsWithPromises.filter(function(a){return a._updatePromises()})},_discardAnimations:function(){this._updateAnimationsPromises(),this._animations=this._animations.filter(function(a){return"finished"!=a.playState&&"idle"!=a.playState})},_play:function(a){var c=new b.Animation(a,this);return this._animations.push(c),b.restartWebAnimationsNextTick(),c._updatePromises(),c._animation.play(),c._updatePromises(),c},play:function(a){return a&&a.remove(),this._play(a)}};var e=!1;b.restartWebAnimationsNextTick=function(){e||(e=!0,requestAnimationFrame(c))};var f=new b.AnimationTimeline;b.timeline=f;try{Object.defineProperty(window.document,"timeline",{configurable:!0,get:function(){return f}})}catch(g){}try{window.document.timeline=f}catch(g){}}(c,e,f),function(a,b){b.animationsWithPromises=[],b.Animation=function(b,c){if(this.effect=b,b&&(b._animation=this),!c)throw new Error("Animation with null timeline is not supported");this._timeline=c,this._sequenceNumber=a.sequenceNumber++,this._holdTime=0,this._paused=!1,this._isGroup=!1,this._animation=null,this._childAnimations=[],this._callback=null,this._oldPlayState="idle",this._rebuildUnderlyingAnimation(),this._animation.cancel(),this._updatePromises()},b.Animation.prototype={_updatePromises:function(){var a=this._oldPlayState,b=this.playState;return this._readyPromise&&b!==a&&("idle"==b?(this._rejectReadyPromise(),this._readyPromise=void 0):"pending"==a?this._resolveReadyPromise():"pending"==b&&(this._readyPromise=void 0)),this._finishedPromise&&b!==a&&("idle"==b?(this._rejectFinishedPromise(),this._finishedPromise=void 0):"finished"==b?this._resolveFinishedPromise():"finished"==a&&(this._finishedPromise=void 0)),this._oldPlayState=this.playState,this._readyPromise||this._finishedPromise},_rebuildUnderlyingAnimation:function(){this._updatePromises();var a,c,d,e,f=this._animation?!0:!1;f&&(a=this.playbackRate,c=this._paused,d=this.startTime,e=this.currentTime,this._animation.cancel(),this._animation._wrapper=null,this._animation=null),(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this._animation=b.newUnderlyingAnimationForKeyframeEffect(this.effect),b.bindAnimationForKeyframeEffect(this)),(this.effect instanceof window.SequenceEffect||this.effect instanceof window.GroupEffect)&&(this._animation=b.newUnderlyingAnimationForGroup(this.effect),b.bindAnimationForGroup(this)),this.effect&&this.effect._onsample&&b.bindAnimationForCustomEffect(this),f&&(1!=a&&(this.playbackRate=a),null!==d?this.startTime=d:null!==e?this.currentTime=e:null!==this._holdTime&&(this.currentTime=this._holdTime),c&&this.pause()),this._updatePromises()
 },_updateChildren:function(){if(this.effect&&"idle"!=this.playState){var a=this.effect._timing.delay;this._childAnimations.forEach(function(c){this._arrangeChildren(c,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c.effect))}.bind(this))}},_setExternalAnimation:function(a){if(this.effect&&this._isGroup)for(var b=0;b<this.effect.children.length;b++)this.effect.children[b]._animation=a,this._childAnimations[b]._setExternalAnimation(a)},_constructChildAnimations:function(){if(this.effect&&this._isGroup){var a=this.effect._timing.delay;this._removeChildAnimations(),this.effect.children.forEach(function(c){var d=window.document.timeline._play(c);this._childAnimations.push(d),d.playbackRate=this.playbackRate,this._paused&&d.pause(),c._animation=this.effect._animation,this._arrangeChildren(d,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c))}.bind(this))}},_arrangeChildren:function(a,b){null===this.startTime?a.currentTime=this.currentTime-b/this.playbackRate:a.startTime!==this.startTime+b/this.playbackRate&&(a.startTime=this.startTime+b/this.playbackRate)},get timeline(){return this._timeline},get playState(){return this._animation?this._animation.playState:"idle"},get finished(){return window.Promise?(this._finishedPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._finishedPromise=new Promise(function(a,b){this._resolveFinishedPromise=function(){a(this)},this._rejectFinishedPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"finished"==this.playState&&this._resolveFinishedPromise()),this._finishedPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get ready(){return window.Promise?(this._readyPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._readyPromise=new Promise(function(a,b){this._resolveReadyPromise=function(){a(this)},this._rejectReadyPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"pending"!==this.playState&&this._resolveReadyPromise()),this._readyPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get onfinish(){return this._onfinish},set onfinish(a){"function"==typeof a?(this._onfinish=a,this._animation.onfinish=function(b){b.target=this,a.call(this,b)}.bind(this)):(this._animation.onfinish=a,this.onfinish=this._animation.onfinish)},get currentTime(){this._updatePromises();var a=this._animation.currentTime;return this._updatePromises(),a},set currentTime(a){this._updatePromises(),this._animation.currentTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.currentTime=a-c}),this._updatePromises()},get startTime(){return this._animation.startTime},set startTime(a){this._updatePromises(),this._animation.startTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.startTime=a+c}),this._updatePromises()},get playbackRate(){return this._animation.playbackRate},set playbackRate(a){this._updatePromises();var b=this.currentTime;this._animation.playbackRate=a,this._forEachChild(function(b){b.playbackRate=a}),"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!==b&&(this.currentTime=b),this._updatePromises()},play:function(){this._updatePromises(),this._paused=!1,this._animation.play(),-1==this._timeline._animations.indexOf(this)&&this._timeline._animations.push(this),this._register(),b.awaitStartTime(this),this._forEachChild(function(a){var b=a.currentTime;a.play(),a.currentTime=b}),this._updatePromises()},pause:function(){this._updatePromises(),this.currentTime&&(this._holdTime=this.currentTime),this._animation.pause(),this._register(),this._forEachChild(function(a){a.pause()}),this._paused=!0,this._updatePromises()},finish:function(){this._updatePromises(),this._animation.finish(),this._register(),this._updatePromises()},cancel:function(){this._updatePromises(),this._animation.cancel(),this._register(),this._removeChildAnimations(),this._updatePromises()},reverse:function(){this._updatePromises();var a=this.currentTime;this._animation.reverse(),this._forEachChild(function(a){a.reverse()}),null!==a&&(this.currentTime=a),this._updatePromises()},addEventListener:function(a,b){var c=b;"function"==typeof b&&(c=function(a){a.target=this,b.call(this,a)}.bind(this),b._wrapper=c),this._animation.addEventListener(a,c)},removeEventListener:function(a,b){this._animation.removeEventListener(a,b&&b._wrapper||b)},_removeChildAnimations:function(){for(;this._childAnimations.length;)this._childAnimations.pop().cancel()},_forEachChild:function(b){var c=0;if(this.effect.children&&this._childAnimations.length<this.effect.children.length&&this._constructChildAnimations(),this._childAnimations.forEach(function(a){b.call(this,a,c),this.effect instanceof window.SequenceEffect&&(c+=a.effect.activeDuration)}.bind(this)),"pending"!=this.playState){var d=this.effect._timing,e=this.currentTime;null!==e&&(e=a.calculateTimeFraction(a.calculateActiveDuration(d),e,d)),(null==e||isNaN(e))&&this._removeChildAnimations()}}},window.Animation=b.Animation}(c,e,f),function(a,b){function c(b){this._frames=a.normalizeKeyframes(b)}function d(){for(var a=!1;h.length;){var b=h.shift();b._updateChildren(),a=!0}return a}var e=function(a){if(a._animation=void 0,a instanceof window.SequenceEffect||a instanceof window.GroupEffect)for(var b=0;b<a.children.length;b++)e(a.children[b])};b.removeMulti=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d._parent?(-1==b.indexOf(d._parent)&&b.push(d._parent),d._parent.children.splice(d._parent.children.indexOf(d),1),d._parent=null,e(d)):d._animation&&d._animation.effect==d&&(d._animation.cancel(),d._animation.effect=new KeyframeEffect(null,[]),d._animation._callback&&(d._animation._callback._animation=null),d._animation._rebuildUnderlyingAnimation(),e(d))}for(c=0;c<b.length;c++)b[c]._rebuild()},b.KeyframeEffect=function(b,d,e){return this.target=b,this._parent=null,e=a.numericTimingToObject(e),this._timingInput=a.cloneTimingInput(e),this._timing=a.normalizeTimingInput(e),this.timing=a.makeTiming(e,!1,this),this.timing._effect=this,"function"==typeof d?(a.deprecated("Custom KeyframeEffect","2015-06-22","Use KeyframeEffect.onsample instead."),this._normalizedKeyframes=d):this._normalizedKeyframes=new c(d),this._keyframes=d,this.activeDuration=a.calculateActiveDuration(this._timing),this},b.KeyframeEffect.prototype={getFrames:function(){return"function"==typeof this._normalizedKeyframes?this._normalizedKeyframes:this._normalizedKeyframes._frames},set onsample(a){if("function"==typeof this.getFrames())throw new Error("Setting onsample on custom effect KeyframeEffect is not supported.");this._onsample=a,this._animation&&this._animation._rebuildUnderlyingAnimation()},get parent(){return this._parent},clone:function(){if("function"==typeof this.getFrames())throw new Error("Cloning custom effects is not supported.");var b=new KeyframeEffect(this.target,[],a.cloneTimingInput(this._timingInput));return b._normalizedKeyframes=this._normalizedKeyframes,b._keyframes=this._keyframes,b},remove:function(){b.removeMulti([this])}};var f=Element.prototype.animate;Element.prototype.animate=function(a,c){return b.timeline._play(new b.KeyframeEffect(this,a,c))};var g=document.createElementNS("http://www.w3.org/1999/xhtml","div");b.newUnderlyingAnimationForKeyframeEffect=function(a){if(a){var b=a.target||g,c=a._keyframes;"function"==typeof c&&(c=[]);var d=a._timingInput}else var b=g,c=[],d=0;return f.apply(b,[c,d])},b.bindAnimationForKeyframeEffect=function(a){a.effect&&"function"==typeof a.effect._normalizedKeyframes&&b.bindAnimationForCustomEffect(a)};var h=[];b.awaitStartTime=function(a){null===a.startTime&&a._isGroup&&(0==h.length&&requestAnimationFrame(d),h.push(a))};var i=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){window.document.timeline._updateAnimationsPromises();var a=i.apply(this,arguments);return d()&&(a=i.apply(this,arguments)),window.document.timeline._updateAnimationsPromises(),a}}),window.KeyframeEffect=b.KeyframeEffect,window.Element.prototype.getAnimations=function(){return document.timeline.getAnimations().filter(function(a){return null!==a.effect&&a.effect.target==this}.bind(this))}}(c,e,f),function(a,b){function c(a){a._registered||(a._registered=!0,f.push(a),g||(g=!0,requestAnimationFrame(d)))}function d(){var a=f;f=[],a.sort(function(a,b){return a._sequenceNumber-b._sequenceNumber}),a=a.filter(function(a){a();var b=a._animation?a._animation.playState:"idle";return"running"!=b&&"pending"!=b&&(a._registered=!1),a._registered}),f.push.apply(f,a),f.length?(g=!0,requestAnimationFrame(d)):g=!1}var e=(document.createElementNS("http://www.w3.org/1999/xhtml","div"),0);b.bindAnimationForCustomEffect=function(b){var d,f=b.effect.target,g="function"==typeof b.effect.getFrames();d=g?b.effect.getFrames():b.effect._onsample;var h=b.effect.timing,i=null;h=a.normalizeTimingInput(h);var j=function(){var c=j._animation?j._animation.currentTime:null;null!==c&&(c=a.calculateTimeFraction(a.calculateActiveDuration(h),c,h),isNaN(c)&&(c=null)),c!==i&&(g?d(c,f,b.effect):d(c,b.effect,b.effect._animation)),i=c};j._animation=b,j._registered=!1,j._sequenceNumber=e++,b._callback=j,c(j)};var f=[],g=!1;b.Animation.prototype._register=function(){this._callback&&c(this._callback)}}(c,e,f),function(a,b){function c(a){return a._timing.delay+a.activeDuration+a._timing.endDelay}function d(b,c){this._parent=null,this.children=b||[],this._reparent(this.children),c=a.numericTimingToObject(c),this._timingInput=a.cloneTimingInput(c),this._timing=a.normalizeTimingInput(c,!0),this.timing=a.makeTiming(c,!0,this),this.timing._effect=this,"auto"===this._timing.duration&&(this._timing.duration=this.activeDuration)}window.SequenceEffect=function(){d.apply(this,arguments)},window.GroupEffect=function(){d.apply(this,arguments)},d.prototype={_isAncestor:function(a){for(var b=this;null!==b;){if(b==a)return!0;b=b._parent}return!1},_rebuild:function(){for(var a=this;a;)"auto"===a.timing.duration&&(a._timing.duration=a.activeDuration),a=a._parent;this._animation&&this._animation._rebuildUnderlyingAnimation()},_reparent:function(a){b.removeMulti(a);for(var c=0;c<a.length;c++)a[c]._parent=this},_putChild:function(a,b){for(var c=b?"Cannot append an ancestor or self":"Cannot prepend an ancestor or self",d=0;d<a.length;d++)if(this._isAncestor(a[d]))throw{type:DOMException.HIERARCHY_REQUEST_ERR,name:"HierarchyRequestError",message:c};for(var d=0;d<a.length;d++)b?this.children.push(a[d]):this.children.unshift(a[d]);this._reparent(a),this._rebuild()},append:function(){this._putChild(arguments,!0)},prepend:function(){this._putChild(arguments,!1)},get parent(){return this._parent},get firstChild(){return this.children.length?this.children[0]:null},get lastChild(){return this.children.length?this.children[this.children.length-1]:null},clone:function(){for(var b=a.cloneTimingInput(this._timingInput),c=[],d=0;d<this.children.length;d++)c.push(this.children[d].clone());return this instanceof GroupEffect?new GroupEffect(c,b):new SequenceEffect(c,b)},remove:function(){b.removeMulti([this])}},window.SequenceEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.SequenceEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a+=c(b)}),Math.max(a,0)}}),window.GroupEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.GroupEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a=Math.max(a,c(b))}),a}}),b.newUnderlyingAnimationForGroup=function(c){var d,e=null,f=function(b){var c=d._wrapper;return c&&"pending"!=c.playState&&c.effect?null==b?void c._removeChildAnimations():0==b&&c.playbackRate<0&&(e||(e=a.normalizeTimingInput(c.effect.timing)),b=a.calculateTimeFraction(a.calculateActiveDuration(e),-1,e),isNaN(b)||null==b)?(c._forEachChild(function(a){a.currentTime=-1}),void c._removeChildAnimations()):void 0:void 0},g=new KeyframeEffect(null,[],c._timing);return g.onsample=f,d=b.timeline._play(g)},b.bindAnimationForGroup=function(a){a._animation._wrapper=a,a._isGroup=!0,b.awaitStartTime(a),a._constructChildAnimations(),a._setExternalAnimation(a)},b.groupChildDuration=c}(c,e,f)}({},function(){return this}());
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// <include src="../../../../ui/webui/resources/js/i18n_template_no_process.js">
-
-i18nTemplate.process(document, loadTimeData);
 (function () {
 function resolve() {
 document.body.removeAttribute('unresolved');
@@ -16320,5 +16323,8 @@
 
   return {Manager: Manager};
 });
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 window.addEventListener('load', downloads.Manager.onLoad);
\ No newline at end of file
diff --git a/chrome/browser/resources/md_downloads/downloads.html b/chrome/browser/resources/md_downloads/downloads.html
index 676c58e..501ce428 100644
--- a/chrome/browser/resources/md_downloads/downloads.html
+++ b/chrome/browser/resources/md_downloads/downloads.html
@@ -5,8 +5,6 @@
   <title i18n-content="title"></title>
   <link rel="stylesheet" href="chrome://resources/css/roboto.css">
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-  <link rel="import" href="chrome://resources/html/polymer_config.html">
-  <link rel="import" href="chrome://downloads/manager.html">
   <style>
     html {
       background: #f2f2f2;
@@ -34,8 +32,11 @@
 <if expr="not is_macosx">
   <command id="undo-command" shortcut="Ctrl-U+005A"><!-- Ctrl+Z -->
 </if>
+  <link rel="import" href="chrome://resources/html/polymer_config.html">
   <link rel="import" href="chrome://resources/html/load_time_data.html">
   <link rel="import" href="chrome://downloads/strings.html">
   <link rel="import" href="chrome://resources/html/i18n_template.html">
+  <link rel="import" href="chrome://downloads/manager.html">
+  <script src="chrome://downloads/downloads.js"></script>
 </body>
 </html>
diff --git a/chrome/browser/resources/md_downloads/downloads.js b/chrome/browser/resources/md_downloads/downloads.js
new file mode 100644
index 0000000..5cbff31
--- /dev/null
+++ b/chrome/browser/resources/md_downloads/downloads.js
@@ -0,0 +1,5 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+window.addEventListener('load', downloads.Manager.onLoad);
diff --git a/chrome/browser/resources/md_downloads/manager.html b/chrome/browser/resources/md_downloads/manager.html
index 3c36dd0..b696a31 100644
--- a/chrome/browser/resources/md_downloads/manager.html
+++ b/chrome/browser/resources/md_downloads/manager.html
@@ -1,7 +1,7 @@
 <link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="chrome://resources/html/load_time_data.html">
 <link rel="import" href="chrome://resources/html/cr/ui.html">
 <link rel="import" href="chrome://resources/html/cr/ui/command.html">
+<link rel="import" href="chrome://resources/html/load_time_data.html">
 <link rel="import" href="chrome://resources/html/util.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
@@ -11,6 +11,12 @@
 <link rel="import" href="chrome://downloads/item.html">
 <link rel="import" href="chrome://downloads/toolbar.html">
 
+<!-- Must be after load_time_data.html. -->
+<link rel="import" href="chrome://downloads/strings.html">
+
+<!-- Must be after strings.html. -->
+<link rel="import" href="chrome://resources/html/i18n_template.html">
+
 <dom-module id="downloads-manager">
   <template>
     <paper-header-panel id="panel" class="loading">
diff --git a/chrome/browser/resources/md_downloads/manager.js b/chrome/browser/resources/md_downloads/manager.js
index e4c54e4..21acd294 100644
--- a/chrome/browser/resources/md_downloads/manager.js
+++ b/chrome/browser/resources/md_downloads/manager.js
@@ -131,5 +131,3 @@
 
   return {Manager: Manager};
 });
-
-window.addEventListener('load', downloads.Manager.onLoad);
diff --git a/chrome/browser/resources/md_downloads/vulcanized.html b/chrome/browser/resources/md_downloads/vulcanized.html
index 3257c473..7ca8903 100644
--- a/chrome/browser/resources/md_downloads/vulcanized.html
+++ b/chrome/browser/resources/md_downloads/vulcanized.html
@@ -48,7 +48,25 @@
 
 </style>
   <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-  <script src="chrome://resources/js/load_time_data.js"></script>
+  <style>
+    html {
+      background: #f2f2f2;
+    }
+
+    html,
+    body {
+      height: 100%;
+    }
+
+    body {
+      display: flex;
+      font-family: Roboto;
+      font-size: 81.25%;
+      margin: 0;
+    }
+  </style>
+<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://downloads/strings.js"></script>
 <style>
   /* IE 10 support for HTML5 hidden attr */
   [hidden] {
@@ -1603,24 +1621,6 @@
 
 
 
-<style>
-    html {
-      background: #f2f2f2;
-    }
-
-    html,
-    body {
-      height: 100%;
-    }
-
-    body {
-      display: flex;
-      font-family: Roboto;
-      font-size: 81.25%;
-      margin: 0;
-    }
-  </style>
-<script src="chrome://downloads/strings.js"></script>
 </head>
 <body><div hidden="" by-vulcanize=""><dom-module id="iron-list" assetpath="chrome://resources/polymer/v1_0/iron-list/">
   <template>
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.js b/chrome/browser/resources/settings/appearance_page/appearance_page.js
index a496acf..0ae02f6e 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.js
+++ b/chrome/browser/resources/settings/appearance_page/appearance_page.js
@@ -68,6 +68,10 @@
     },
   },
 
+  behaviors: [
+    I18nBehavior,
+  ],
+
   ready: function() {
     this.$.defaultFontSize.menuOptions = this.fontSizeOptions_;
   },
diff --git a/chrome/browser/safe_browsing/database_manager.h b/chrome/browser/safe_browsing/database_manager.h
index cc0840b8..8a438c7 100644
--- a/chrome/browser/safe_browsing/database_manager.h
+++ b/chrome/browser/safe_browsing/database_manager.h
@@ -15,7 +15,7 @@
 #include <vector>
 
 #include "base/memory/ref_counted.h"
-#include "chrome/browser/safe_browsing/safe_browsing_util.h"
+#include "components/safe_browsing_db/util.h"
 #include "content/public/common/resource_type.h"
 #include "url/gurl.h"
 
diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
index 8e327773..cbe556e 100644
--- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
@@ -204,7 +204,7 @@
           arg0,
           std::vector<SBFullHash>(),
           arg1,
-          safe_browsing_util::BINURL,
+          safe_browsing::BINURL,
           std::vector<SBThreatType>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL));
   for (size_t i = 0; i < check->url_results.size(); ++i)
     check->url_results[i] = threat_type;
diff --git a/chrome/browser/safe_browsing/local_database_manager.cc b/chrome/browser/safe_browsing/local_database_manager.cc
index f50e0989..9f23af35 100644
--- a/chrome/browser/safe_browsing/local_database_manager.cc
+++ b/chrome/browser/safe_browsing/local_database_manager.cc
@@ -32,6 +32,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
+#include "components/safe_browsing_db/util.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "url/url_constants.h"
@@ -47,7 +48,7 @@
 // |true| if there were any prefix hits in |full_hashes|.
 void RecordGetHashCheckStatus(
     bool hit,
-    safe_browsing_util::ListType check_type,
+    safe_browsing::ListType check_type,
     const std::vector<SBFullHashResult>& full_hashes) {
   SafeBrowsingProtocolManager::ResultType result;
   if (full_hashes.empty()) {
@@ -57,7 +58,7 @@
   } else {
     result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_MISS;
   }
-  bool is_download = check_type == safe_browsing_util::BINURL;
+  bool is_download = check_type == safe_browsing::BINURL;
   SafeBrowsingProtocolManager::RecordGetHashResult(is_download, result);
 }
 
@@ -71,32 +72,32 @@
 
 // Return the severest list id from the results in |full_hashes| which matches
 // |hash|, or INVALID if none match.
-safe_browsing_util::ListType GetHashSeverestThreatListType(
+safe_browsing::ListType GetHashSeverestThreatListType(
     const SBFullHash& hash,
     const std::vector<SBFullHashResult>& full_hashes,
     size_t* index) {
-  safe_browsing_util::ListType pending_threat = safe_browsing_util::INVALID;
+  safe_browsing::ListType pending_threat = safe_browsing::INVALID;
   for (size_t i = 0; i < full_hashes.size(); ++i) {
-    if (SBFullHashEqual(hash, full_hashes[i].hash)) {
-      const safe_browsing_util::ListType threat =
-          static_cast<safe_browsing_util::ListType>(full_hashes[i].list_id);
+    if (safe_browsing::SBFullHashEqual(hash, full_hashes[i].hash)) {
+      const safe_browsing::ListType threat =
+          static_cast<safe_browsing::ListType>(full_hashes[i].list_id);
       switch (threat) {
-        case safe_browsing_util::INVALID:
+        case safe_browsing::INVALID:
           // |full_hashes| should never contain INVALID as a |list_id|.
           NOTREACHED();
           break;
-        case safe_browsing_util::MALWARE:                  // Falls through.
-        case safe_browsing_util::PHISH:                    // Falls through.
-        case safe_browsing_util::BINURL:                   // Falls through.
-        case safe_browsing_util::CSDWHITELIST:             // Falls through.
-        case safe_browsing_util::DOWNLOADWHITELIST:        // Falls through.
-        case safe_browsing_util::INCLUSIONWHITELIST:       // Falls through.
-        case safe_browsing_util::EXTENSIONBLACKLIST:       // Falls through.
-        case safe_browsing_util::IPBLACKLIST:
+        case safe_browsing::MALWARE:                  // Falls through.
+        case safe_browsing::PHISH:                    // Falls through.
+        case safe_browsing::BINURL:                   // Falls through.
+        case safe_browsing::CSDWHITELIST:             // Falls through.
+        case safe_browsing::DOWNLOADWHITELIST:        // Falls through.
+        case safe_browsing::INCLUSIONWHITELIST:       // Falls through.
+        case safe_browsing::EXTENSIONBLACKLIST:       // Falls through.
+        case safe_browsing::IPBLACKLIST:
           if (index)
             *index = i;
           return threat;
-        case safe_browsing_util::UNWANTEDURL:
+        case safe_browsing::UNWANTEDURL:
           // UNWANTEDURL is considered less severe than other threats, keep
           // looking.
           pending_threat = threat;
@@ -112,34 +113,34 @@
 // Given a URL, compare all the possible host + path full hashes to the set of
 // provided full hashes.  Returns the list id of the severest matching result
 // from |full_hashes|, or INVALID if none match.
-safe_browsing_util::ListType GetUrlSeverestThreatListType(
+safe_browsing::ListType GetUrlSeverestThreatListType(
     const GURL& url,
     const std::vector<SBFullHashResult>& full_hashes,
     size_t* index) {
   if (full_hashes.empty())
-    return safe_browsing_util::INVALID;
+    return safe_browsing::INVALID;
 
   std::vector<std::string> patterns;
-  safe_browsing_util::GeneratePatternsToCheck(url, &patterns);
+  safe_browsing::GeneratePatternsToCheck(url, &patterns);
 
-  safe_browsing_util::ListType pending_threat = safe_browsing_util::INVALID;
+  safe_browsing::ListType pending_threat = safe_browsing::INVALID;
   for (size_t i = 0; i < patterns.size(); ++i) {
-    safe_browsing_util::ListType threat = GetHashSeverestThreatListType(
-        SBFullHashForString(patterns[i]), full_hashes, index);
+    safe_browsing::ListType threat = GetHashSeverestThreatListType(
+        safe_browsing::SBFullHashForString(patterns[i]), full_hashes, index);
     switch (threat) {
-      case safe_browsing_util::INVALID:
+      case safe_browsing::INVALID:
         // Ignore patterns with no matching threat.
         break;
-      case safe_browsing_util::MALWARE:                  // Falls through.
-      case safe_browsing_util::PHISH:                    // Falls through.
-      case safe_browsing_util::BINURL:                   // Falls through.
-      case safe_browsing_util::CSDWHITELIST:             // Falls through.
-      case safe_browsing_util::DOWNLOADWHITELIST:        // Falls through.
-      case safe_browsing_util::INCLUSIONWHITELIST:       // Falls through.
-      case safe_browsing_util::EXTENSIONBLACKLIST:       // Falls through.
-      case safe_browsing_util::IPBLACKLIST:
+      case safe_browsing::MALWARE:                  // Falls through.
+      case safe_browsing::PHISH:                    // Falls through.
+      case safe_browsing::BINURL:                   // Falls through.
+      case safe_browsing::CSDWHITELIST:             // Falls through.
+      case safe_browsing::DOWNLOADWHITELIST:        // Falls through.
+      case safe_browsing::INCLUSIONWHITELIST:       // Falls through.
+      case safe_browsing::EXTENSIONBLACKLIST:       // Falls through.
+      case safe_browsing::IPBLACKLIST:
         return threat;
-      case safe_browsing_util::UNWANTEDURL:
+      case safe_browsing::UNWANTEDURL:
         // UNWANTEDURL is considered less severe than other threats, keep
         // looking.
         pending_threat = threat;
@@ -149,17 +150,17 @@
   return pending_threat;
 }
 
-SBThreatType GetThreatTypeFromListType(safe_browsing_util::ListType list_type) {
+SBThreatType GetThreatTypeFromListType(safe_browsing::ListType list_type) {
   switch (list_type) {
-    case safe_browsing_util::PHISH:
+    case safe_browsing::PHISH:
       return SB_THREAT_TYPE_URL_PHISHING;
-    case safe_browsing_util::MALWARE:
+    case safe_browsing::MALWARE:
       return SB_THREAT_TYPE_URL_MALWARE;
-    case safe_browsing_util::UNWANTEDURL:
+    case safe_browsing::UNWANTEDURL:
       return SB_THREAT_TYPE_URL_UNWANTED;
-    case safe_browsing_util::BINURL:
+    case safe_browsing::BINURL:
       return SB_THREAT_TYPE_BINARY_MALWARE_URL;
-    case safe_browsing_util::EXTENSIONBLACKLIST:
+    case safe_browsing::EXTENSIONBLACKLIST:
       return SB_THREAT_TYPE_EXTENSION;
     default:
       DVLOG(1) << "Unknown safe browsing list id " << list_type;
@@ -190,7 +191,7 @@
     const std::vector<GURL>& urls,
     const std::vector<SBFullHash>& full_hashes,
     Client* client,
-    safe_browsing_util::ListType check_type,
+    safe_browsing::ListType check_type,
     const std::vector<SBThreatType>& expected_threats)
     : urls(urls),
       url_results(urls.size(), SB_THREAT_TYPE_SAFE),
@@ -218,14 +219,14 @@
   if (!urls.empty()) {
     DCHECK(full_hashes.empty());
     switch (check_type) {
-      case safe_browsing_util::MALWARE:
-      case safe_browsing_util::PHISH:
-      case safe_browsing_util::UNWANTEDURL:
+      case safe_browsing::MALWARE:
+      case safe_browsing::PHISH:
+      case safe_browsing::UNWANTEDURL:
         DCHECK_EQ(1u, urls.size());
         client->OnCheckBrowseUrlResult(urls[0], url_results[0],
                                        url_metadata[0]);
         break;
-      case safe_browsing_util::BINURL:
+      case safe_browsing::BINURL:
         DCHECK_EQ(urls.size(), url_results.size());
         client->OnCheckDownloadUrlResult(
             urls, *std::max_element(url_results.begin(), url_results.end()));
@@ -235,11 +236,11 @@
     }
   } else if (!full_hashes.empty()) {
     switch (check_type) {
-      case safe_browsing_util::EXTENSIONBLACKLIST: {
+      case safe_browsing::EXTENSIONBLACKLIST: {
         std::set<std::string> unsafe_extension_ids;
         for (size_t i = 0; i < full_hashes.size(); ++i) {
           std::string extension_id =
-              safe_browsing_util::SBFullHashToString(full_hashes[i]);
+              safe_browsing::SBFullHashToString(full_hashes[i]);
           if (full_hash_results[i] == SB_THREAT_TYPE_EXTENSION)
             unsafe_extension_ids.insert(extension_id);
         }
@@ -338,7 +339,7 @@
       new SafeBrowsingCheck(url_chain,
                             std::vector<SBFullHash>(),
                             client,
-                            safe_browsing_util::BINURL,
+                            safe_browsing::BINURL,
                             std::vector<SBThreatType>(1,
                                 SB_THREAT_TYPE_BINARY_MALWARE_URL));
   std::vector<SBPrefix> prefixes;
@@ -361,7 +362,7 @@
   std::vector<SBFullHash> extension_id_hashes;
   std::transform(extension_ids.begin(), extension_ids.end(),
                  std::back_inserter(extension_id_hashes),
-                 safe_browsing_util::StringToSBFullHash);
+                 safe_browsing::StringToSBFullHash);
   std::vector<SBPrefix> prefixes;
   for (const SBFullHash& hash : extension_id_hashes)
     prefixes.push_back(hash.prefix);
@@ -370,7 +371,7 @@
       std::vector<GURL>(),
       extension_id_hashes,
       client,
-      safe_browsing_util::EXTENSIONBLACKLIST,
+      safe_browsing::EXTENSIONBLACKLIST,
       std::vector<SBThreatType>(1, SB_THREAT_TYPE_EXTENSION));
   StartSafeBrowsingCheck(
       check,
@@ -458,7 +459,7 @@
 
   const base::TimeTicks start = base::TimeTicks::Now();
   if (!MakeDatabaseAvailable()) {
-    QueuedCheck queued_check(safe_browsing_util::MALWARE,  // or PHISH
+    QueuedCheck queued_check(safe_browsing::MALWARE,  // or PHISH
                              client,
                              url,
                              expected_threats,
@@ -509,7 +510,7 @@
   SafeBrowsingCheck* check = new SafeBrowsingCheck(std::vector<GURL>(1, url),
                                                    std::vector<SBFullHash>(),
                                                    client,
-                                                   safe_browsing_util::MALWARE,
+                                                   safe_browsing::MALWARE,
                                                    expected_threats);
   check->need_get_hash = cache_hits.empty();
   check->prefix_hits.swap(prefix_hits);
@@ -671,7 +672,7 @@
 }
 
 LocalSafeBrowsingDatabaseManager::QueuedCheck::QueuedCheck(
-    const safe_browsing_util::ListType check_type,
+    const safe_browsing::ListType check_type,
     Client* client,
     const GURL& url,
     const std::vector<SBThreatType>& expected_threats,
@@ -871,7 +872,7 @@
   if (!enabled_)
     return;
 
-  bool is_download = check->check_type == safe_browsing_util::BINURL;
+  bool is_download = check->check_type == safe_browsing::BINURL;
   sb_service_->protocol_manager()->GetFullHash(
       check->prefix_hits,
       base::Bind(&LocalSafeBrowsingDatabaseManager::HandleGetHashResults,
@@ -1024,7 +1025,7 @@
     SafeBrowsingCheck* check,
     const std::vector<SBFullHashResult>& full_hashes) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  safe_browsing_util::ListType check_type = check->check_type;
+  safe_browsing::ListType check_type = check->check_type;
   SBPrefix prefix = check->prefix_hits[0];
   GetHashRequests::iterator it = gethash_requests_.find(prefix);
   if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) {
diff --git a/chrome/browser/safe_browsing/local_database_manager.h b/chrome/browser/safe_browsing/local_database_manager.h
index 509a6041..a848f1a6 100644
--- a/chrome/browser/safe_browsing/local_database_manager.h
+++ b/chrome/browser/safe_browsing/local_database_manager.h
@@ -24,7 +24,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/safe_browsing/database_manager.h"
 #include "chrome/browser/safe_browsing/protocol_manager.h"
-#include "chrome/browser/safe_browsing/safe_browsing_util.h"
+#include "components/safe_browsing_db/util.h"
 #include "url/gurl.h"
 
 class SafeBrowsingService;
@@ -57,7 +57,7 @@
     SafeBrowsingCheck(const std::vector<GURL>& urls,
                       const std::vector<SBFullHash>& full_hashes,
                       Client* client,
-                      safe_browsing_util::ListType check_type,
+                      safe_browsing::ListType check_type,
                       const std::vector<SBThreatType>& expected_threats);
     ~SafeBrowsingCheck();
 
@@ -74,7 +74,7 @@
     bool is_extended_reporting;
     bool need_get_hash;
     base::TimeTicks start;  // When check was sent to SB service.
-    safe_browsing_util::ListType check_type;  // See comment in constructor.
+    safe_browsing::ListType check_type;  // See comment in constructor.
     std::vector<SBThreatType> expected_threats;
     std::vector<SBPrefix> prefix_hits;
     std::vector<SBFullHashResult> cache_hits;
@@ -154,13 +154,13 @@
 
   // Clients that we've queued up for checking later once the database is ready.
   struct QueuedCheck {
-    QueuedCheck(const safe_browsing_util::ListType check_type,
+    QueuedCheck(const safe_browsing::ListType check_type,
                 Client* client,
                 const GURL& url,
                 const std::vector<SBThreatType>& expected_threats,
                 const base::TimeTicks& start);
     ~QueuedCheck();
-    safe_browsing_util::ListType check_type;
+    safe_browsing::ListType check_type;
     Client* client;
     GURL url;
     std::vector<SBThreatType> expected_threats;
diff --git a/chrome/browser/safe_browsing/local_database_manager_unittest.cc b/chrome/browser/safe_browsing/local_database_manager_unittest.cc
index de8dc96..b4bbc30 100644
--- a/chrome/browser/safe_browsing/local_database_manager_unittest.cc
+++ b/chrome/browser/safe_browsing/local_database_manager_unittest.cc
@@ -40,7 +40,7 @@
 
 class SafeBrowsingDatabaseManagerTest : public PlatformTest {
  public:
-  bool RunSBHashTest(const safe_browsing_util::ListType list_type,
+  bool RunSBHashTest(const safe_browsing::ListType list_type,
                      const std::vector<SBThreatType>& expected_threats,
                      const std::string& result_list);
 
@@ -49,7 +49,7 @@
 };
 
 bool SafeBrowsingDatabaseManagerTest::RunSBHashTest(
-    const safe_browsing_util::ListType list_type,
+    const safe_browsing::ListType list_type,
     const std::vector<SBThreatType>& expected_threats,
     const std::string& result_list) {
   scoped_refptr<SafeBrowsingService> sb_service_(
@@ -69,7 +69,7 @@
 
   const SBFullHashResult full_hash_result = {
       same_full_hash,
-      safe_browsing_util::GetListId(result_list)
+      safe_browsing::GetListId(result_list)
   };
 
   std::vector<SBFullHashResult> fake_results(1, full_hash_result);
@@ -82,23 +82,23 @@
 TEST_F(SafeBrowsingDatabaseManagerTest, CheckCorrespondsListType) {
   std::vector<SBThreatType> malware_threat(1,
                                            SB_THREAT_TYPE_BINARY_MALWARE_URL);
-  EXPECT_FALSE(RunSBHashTest(safe_browsing_util::BINURL,
+  EXPECT_FALSE(RunSBHashTest(safe_browsing::BINURL,
                              malware_threat,
-                             safe_browsing_util::kMalwareList));
-  EXPECT_TRUE(RunSBHashTest(safe_browsing_util::BINURL,
+                             safe_browsing::kMalwareList));
+  EXPECT_TRUE(RunSBHashTest(safe_browsing::BINURL,
                             malware_threat,
-                            safe_browsing_util::kBinUrlList));
+                            safe_browsing::kBinUrlList));
 
   // Check for multiple threats
   std::vector<SBThreatType> multiple_threats;
   multiple_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
   multiple_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
-  EXPECT_FALSE(RunSBHashTest(safe_browsing_util::MALWARE,
+  EXPECT_FALSE(RunSBHashTest(safe_browsing::MALWARE,
                              multiple_threats,
-                             safe_browsing_util::kBinUrlList));
-  EXPECT_TRUE(RunSBHashTest(safe_browsing_util::MALWARE,
+                             safe_browsing::kBinUrlList));
+  EXPECT_TRUE(RunSBHashTest(safe_browsing::MALWARE,
                             multiple_threats,
-                            safe_browsing_util::kMalwareList));
+                            safe_browsing::kMalwareList));
 }
 
 TEST_F(SafeBrowsingDatabaseManagerTest, GetUrlSeverestThreatType) {
@@ -111,31 +111,35 @@
       "http://www.unwantedandmalware.com/page.html");
   const GURL kSafeUrl("http://www.safe.com/page.html");
 
-  const SBFullHash kMalwareHostHash = SBFullHashForString("malware.com/");
-  const SBFullHash kPhishingHostHash = SBFullHashForString("phishing.com/");
-  const SBFullHash kUnwantedHostHash = SBFullHashForString("unwanted.com/");
+  const SBFullHash kMalwareHostHash =
+      safe_browsing::SBFullHashForString("malware.com/");
+  const SBFullHash kPhishingHostHash =
+      safe_browsing::SBFullHashForString("phishing.com/");
+  const SBFullHash kUnwantedHostHash =
+      safe_browsing::SBFullHashForString("unwanted.com/");
   const SBFullHash kUnwantedAndMalwareHostHash =
-      SBFullHashForString("unwantedandmalware.com/");
-  const SBFullHash kSafeHostHash = SBFullHashForString("www.safe.com/");
+      safe_browsing::SBFullHashForString("unwantedandmalware.com/");
+  const SBFullHash kSafeHostHash =
+      safe_browsing::SBFullHashForString("www.safe.com/");
 
   {
     SBFullHashResult full_hash;
     full_hash.hash = kMalwareHostHash;
-    full_hash.list_id = static_cast<int>(safe_browsing_util::MALWARE);
+    full_hash.list_id = static_cast<int>(safe_browsing::MALWARE);
     full_hashes.push_back(full_hash);
   }
 
   {
     SBFullHashResult full_hash;
     full_hash.hash = kPhishingHostHash;
-    full_hash.list_id = static_cast<int>(safe_browsing_util::PHISH);
+    full_hash.list_id = static_cast<int>(safe_browsing::PHISH);
     full_hashes.push_back(full_hash);
   }
 
   {
     SBFullHashResult full_hash;
     full_hash.hash = kUnwantedHostHash;
-    full_hash.list_id = static_cast<int>(safe_browsing_util::UNWANTEDURL);
+    full_hash.list_id = static_cast<int>(safe_browsing::UNWANTEDURL);
     full_hashes.push_back(full_hash);
   }
 
@@ -144,13 +148,12 @@
     // kUnwantedAndMalwareHostHash.
     SBFullHashResult full_hash_malware;
     full_hash_malware.hash = kUnwantedAndMalwareHostHash;
-    full_hash_malware.list_id = static_cast<int>(safe_browsing_util::MALWARE);
+    full_hash_malware.list_id = static_cast<int>(safe_browsing::MALWARE);
     full_hashes.push_back(full_hash_malware);
 
     SBFullHashResult full_hash_unwanted;
     full_hash_unwanted.hash = kUnwantedAndMalwareHostHash;
-    full_hash_unwanted.list_id =
-        static_cast<int>(safe_browsing_util::UNWANTEDURL);
+    full_hash_unwanted.list_id = static_cast<int>(safe_browsing::UNWANTEDURL);
     full_hashes.push_back(full_hash_unwanted);
   }
 
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc
index 745a9d7f..658453b 100644
--- a/chrome/browser/safe_browsing/protocol_manager.cc
+++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -18,6 +18,7 @@
 #include "base/timer/timer.h"
 #include "chrome/browser/safe_browsing/protocol_parser.h"
 #include "chrome/common/env_vars.h"
+#include "components/safe_browsing_db/util.h"
 #include "components/variations/variations_associated_data.h"
 #include "google_apis/google_api_keys.h"
 #include "net/base/escape.h"
@@ -631,10 +632,10 @@
   bool found_phishing = false;
   for (size_t i = 0; i < lists.size(); ++i) {
     update_list_data_.append(safe_browsing::FormatList(lists[i]));
-    if (lists[i].name == safe_browsing_util::kPhishingList)
+    if (lists[i].name == safe_browsing::kPhishingList)
       found_phishing = true;
 
-    if (lists[i].name == safe_browsing_util::kMalwareList)
+    if (lists[i].name == safe_browsing::kMalwareList)
       found_malware = true;
   }
 
@@ -645,11 +646,11 @@
   // removed.
   if (!found_phishing) {
     update_list_data_.append(safe_browsing::FormatList(
-        SBListChunkRanges(safe_browsing_util::kPhishingList)));
+        SBListChunkRanges(safe_browsing::kPhishingList)));
   }
   if (!found_malware) {
     update_list_data_.append(safe_browsing::FormatList(
-        SBListChunkRanges(safe_browsing_util::kMalwareList)));
+        SBListChunkRanges(safe_browsing::kMalwareList)));
   }
 
   // Large requests are (probably) a sign of database corruption.
diff --git a/chrome/browser/safe_browsing/protocol_manager_unittest.cc b/chrome/browser/safe_browsing/protocol_manager_unittest.cc
index 31b18f9..d1705df 100644
--- a/chrome/browser/safe_browsing/protocol_manager_unittest.cc
+++ b/chrome/browser/safe_browsing/protocol_manager_unittest.cc
@@ -408,7 +408,7 @@
   net::TestURLFetcherFactory url_fetcher_factory;
 
   std::vector<SBListChunkRanges> ranges;
-  SBListChunkRanges range_phish(safe_browsing_util::kPhishingList);
+  SBListChunkRanges range_phish(safe_browsing::kPhishingList);
   range_phish.adds = "adds_phish";
   range_phish.subs = "subs_phish";
   ranges.push_back(range_phish);
diff --git a/chrome/browser/safe_browsing/protocol_parser.cc b/chrome/browser/safe_browsing/protocol_parser.cc
index 05378c46..135e76f6 100644
--- a/chrome/browser/safe_browsing/protocol_parser.cc
+++ b/chrome/browser/safe_browsing/protocol_parser.cc
@@ -199,7 +199,7 @@
       return false;
 
     SBFullHashResult full_hash;
-    full_hash.list_id = safe_browsing_util::GetListId(cmd_parts[0]);
+    full_hash.list_id = safe_browsing::GetListId(cmd_parts[0]);
 
     size_t hash_len;
     if (!base::StringToSizeT(cmd_parts[1], &hash_len))
diff --git a/chrome/browser/safe_browsing/protocol_parser_unittest.cc b/chrome/browser/safe_browsing/protocol_parser_unittest.cc
index 70872b3e..d145b81 100644
--- a/chrome/browser/safe_browsing/protocol_parser_unittest.cc
+++ b/chrome/browser/safe_browsing/protocol_parser_unittest.cc
@@ -88,8 +88,10 @@
   EXPECT_TRUE(chunks[0]->IsFullHash());
 
   ASSERT_EQ(2U, chunks[0]->FullHashCount());
-  EXPECT_TRUE(SBFullHashEqual(chunks[0]->FullHashAt(0), full_hash1));
-  EXPECT_TRUE(SBFullHashEqual(chunks[0]->FullHashAt(1), full_hash2));
+  EXPECT_TRUE(
+      safe_browsing::SBFullHashEqual(chunks[0]->FullHashAt(0), full_hash1));
+  EXPECT_TRUE(
+      safe_browsing::SBFullHashEqual(chunks[0]->FullHashAt(1), full_hash2));
 }
 
 // Test parsing multiple add chunks. We'll use the same chunk as above, and add
@@ -282,9 +284,11 @@
   EXPECT_TRUE(chunks[0]->IsFullHash());
 
   ASSERT_EQ(2U, chunks[0]->FullHashCount());
-  EXPECT_TRUE(SBFullHashEqual(chunks[0]->FullHashAt(0), full_hash1));
+  EXPECT_TRUE(
+      safe_browsing::SBFullHashEqual(chunks[0]->FullHashAt(0), full_hash1));
   EXPECT_EQ(7, chunks[0]->AddChunkNumberAt(0));
-  EXPECT_TRUE(SBFullHashEqual(chunks[0]->FullHashAt(1), full_hash2));
+  EXPECT_TRUE(
+      safe_browsing::SBFullHashEqual(chunks[0]->FullHashAt(1), full_hash2));
   EXPECT_EQ(9, chunks[0]->AddChunkNumberAt(1));
 }
 
@@ -396,15 +400,15 @@
   EXPECT_EQ(memcmp(&full_hashes[0].hash,
                    "00112233445566778899aabbccddeeff",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::PHISH, full_hashes[0].list_id);
+  EXPECT_EQ(safe_browsing::PHISH, full_hashes[0].list_id);
   EXPECT_EQ(memcmp(&full_hashes[1].hash,
                    "00001111222233334444555566667777",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::PHISH, full_hashes[1].list_id);
+  EXPECT_EQ(safe_browsing::PHISH, full_hashes[1].list_id);
   EXPECT_EQ(memcmp(&full_hashes[2].hash,
                    "ffffeeeeddddccccbbbbaaaa99998888",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::PHISH, full_hashes[2].list_id);
+  EXPECT_EQ(safe_browsing::PHISH, full_hashes[2].list_id);
 
   // Test multiple lists in the GetHash results.
   const std::string get_hash2(base::StringPrintf(
@@ -423,15 +427,15 @@
   EXPECT_EQ(memcmp(&full_hashes[0].hash,
                    "00112233445566778899aabbccddeeff",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::PHISH, full_hashes[0].list_id);
+  EXPECT_EQ(safe_browsing::PHISH, full_hashes[0].list_id);
   EXPECT_EQ(memcmp(&full_hashes[1].hash,
                    "cafebeefcafebeefdeaddeaddeaddead",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::MALWARE, full_hashes[1].list_id);
+  EXPECT_EQ(safe_browsing::MALWARE, full_hashes[1].list_id);
   EXPECT_EQ(memcmp(&full_hashes[2].hash,
                    "zzzzyyyyxxxxwwwwvvvvuuuuttttssss",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::MALWARE, full_hashes[2].list_id);
+  EXPECT_EQ(safe_browsing::MALWARE, full_hashes[2].list_id);
 
   // Test metadata parsing.
   const std::string get_hash3(base::StringPrintf(
@@ -451,17 +455,17 @@
   EXPECT_EQ(memcmp(&full_hashes[0].hash,
                    "zzzzyyyyxxxxwwwwvvvvuuuuttttssss",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::MALWARE, full_hashes[0].list_id);
+  EXPECT_EQ(safe_browsing::MALWARE, full_hashes[0].list_id);
   EXPECT_EQ(std::string("ab"), full_hashes[0].metadata);
   EXPECT_EQ(memcmp(&full_hashes[1].hash,
                    "00112233445566778899aabbccddeeff",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::MALWARE, full_hashes[1].list_id);
+  EXPECT_EQ(safe_browsing::MALWARE, full_hashes[1].list_id);
   EXPECT_EQ(std::string("xy"), full_hashes[1].metadata);
   EXPECT_EQ(memcmp(&full_hashes[2].hash,
                    "cafebeefcafebeefdeaddeaddeaddead",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::PHISH, full_hashes[2].list_id);
+  EXPECT_EQ(safe_browsing::PHISH, full_hashes[2].list_id);
   EXPECT_EQ(std::string(), full_hashes[2].metadata);
 }
 
@@ -483,7 +487,7 @@
   ASSERT_EQ(1U, full_hashes.size());
   EXPECT_EQ(memcmp("12345678901234567890123456789012",
                    &full_hashes[0].hash, sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::PHISH, full_hashes[0].list_id);
+  EXPECT_EQ(safe_browsing::PHISH, full_hashes[0].list_id);
 
   hash_response += base::StringPrintf(
       "%s:32:1\n"
@@ -498,10 +502,10 @@
   EXPECT_EQ(2U, full_hashes.size());
   EXPECT_EQ(memcmp("12345678901234567890123456789012",
                    &full_hashes[0].hash, sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::PHISH, full_hashes[0].list_id);
+  EXPECT_EQ(safe_browsing::PHISH, full_hashes[0].list_id);
   EXPECT_EQ(memcmp("abcdefghijklmnopqrstuvwxyz123457",
                    &full_hashes[1].hash, sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::MALWARE, full_hashes[1].list_id);
+  EXPECT_EQ(safe_browsing::MALWARE, full_hashes[1].list_id);
 }
 
 TEST(SafeBrowsingProtocolParsingTest, TestGetHashWithUnknownListAndMetadata) {
@@ -523,7 +527,7 @@
   EXPECT_EQ(memcmp(&full_hashes[0].hash,
                    "0123456789hashhashhashhashhashha",
                    sizeof(SBFullHash)), 0);
-  EXPECT_EQ(safe_browsing_util::MALWARE, full_hashes[0].list_id);
+  EXPECT_EQ(safe_browsing::MALWARE, full_hashes[0].list_id);
   EXPECT_EQ(std::string(), full_hashes[0].metadata);
 }
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index 92c7c85..9decd2a 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -92,7 +92,7 @@
         std::vector<GURL>(1, gurl),
         std::vector<SBFullHash>(),
         client,
-        safe_browsing_util::MALWARE,
+        safe_browsing::MALWARE,
         expected_threats);
     sb_check.url_results[0] = badurls[gurl.spec()];
     sb_check.OnSafeBrowsingResult();
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.cc b/chrome/browser/safe_browsing/safe_browsing_database.cc
index 81948a6..80c16f7b 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database.cc
@@ -107,7 +107,7 @@
   return encoded_chunk_id >> 1;
 }
 int EncodeChunkId(const int chunk, const int list_id) {
-  DCHECK_NE(list_id, safe_browsing_util::INVALID);
+  DCHECK_NE(list_id, safe_browsing::INVALID);
   return chunk << 1 | list_id % 2;
 }
 
@@ -128,16 +128,17 @@
   if (url.HostIsIPAddress()) {
     hosts.push_back(url.host());
   } else {
-    safe_browsing_util::GenerateHostsToCheck(url, &hosts);
+    safe_browsing::GenerateHostsToCheck(url, &hosts);
   }
 
   std::vector<std::string> paths;
-  safe_browsing_util::GeneratePathsToCheck(url, &paths);
+  safe_browsing::GeneratePathsToCheck(url, &paths);
 
   for (size_t i = 0; i < hosts.size(); ++i) {
     for (size_t j = 0; j < paths.size(); ++j) {
       const std::string& path = paths[j];
-      full_hashes->push_back(SBFullHashForString(hosts[i] + path));
+      full_hashes->push_back(safe_browsing::SBFullHashForString(
+          hosts[i] + path));
 
       // We may have /foo as path-prefix in the whitelist which should
       // also match with /foo/bar and /foo?bar.  Hence, for every path
@@ -146,7 +147,8 @@
           path.size() > 1 &&
           path[path.size() - 1] == '/') {
         full_hashes->push_back(
-            SBFullHashForString(hosts[i] + path.substr(0, path.size() - 1)));
+            safe_browsing::SBFullHashForString(
+                hosts[i] + path.substr(0, path.size() - 1)));
       }
     }
   }
@@ -230,10 +232,10 @@
 
   for (size_t i = 0; i < listnames.size(); ++i) {
     const std::string& listname = listnames[i];
-    DCHECK_EQ(safe_browsing_util::GetListId(listname) % 2,
+    DCHECK_EQ(safe_browsing::GetListId(listname) % 2,
               static_cast<int>(i % 2));
-    DCHECK_NE(safe_browsing_util::GetListId(listname),
-              safe_browsing_util::INVALID);
+    DCHECK_NE(safe_browsing::GetListId(listname),
+              safe_browsing::INVALID);
     lists->push_back(SBListChunkRanges(listname));
     lists->back().adds.swap(adds[i]);
     lists->back().subs.swap(subs[i]);
@@ -289,7 +291,7 @@
   // Find full-hash matches.
   std::vector<SBFullHashResult>& cached_hashes = cached_result.full_hashes;
   for (size_t i = 0; i < cached_hashes.size(); ++i) {
-    if (SBFullHashEqual(full_hash, cached_hashes[i].hash))
+    if (safe_browsing::SBFullHashEqual(full_hash, cached_hashes[i].hash))
       results->push_back(cached_hashes[i]);
   }
 
@@ -445,22 +447,22 @@
   // Stores are not thread safe.
   DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
 
-  if (list_id == safe_browsing_util::PHISH ||
-      list_id == safe_browsing_util::MALWARE) {
+  if (list_id == safe_browsing::PHISH ||
+      list_id == safe_browsing::MALWARE) {
     return browse_store_.get();
-  } else if (list_id == safe_browsing_util::BINURL) {
+  } else if (list_id == safe_browsing::BINURL) {
     return download_store_.get();
-  } else if (list_id == safe_browsing_util::CSDWHITELIST) {
+  } else if (list_id == safe_browsing::CSDWHITELIST) {
     return csd_whitelist_store_.get();
-  } else if (list_id == safe_browsing_util::DOWNLOADWHITELIST) {
+  } else if (list_id == safe_browsing::DOWNLOADWHITELIST) {
     return download_whitelist_store_.get();
-  } else if (list_id == safe_browsing_util::INCLUSIONWHITELIST) {
+  } else if (list_id == safe_browsing::INCLUSIONWHITELIST) {
     return inclusion_whitelist_store_.get();
-  } else if (list_id == safe_browsing_util::EXTENSIONBLACKLIST) {
+  } else if (list_id == safe_browsing::EXTENSIONBLACKLIST) {
     return extension_blacklist_store_.get();
-  } else if (list_id == safe_browsing_util::IPBLACKLIST) {
+  } else if (list_id == safe_browsing::IPBLACKLIST) {
     return ip_blacklist_store_.get();
-  } else if (list_id == safe_browsing_util::UNWANTEDURL) {
+  } else if (list_id == safe_browsing::UNWANTEDURL) {
     return unwanted_software_store_.get();
   }
   return NULL;
@@ -915,7 +917,7 @@
     return false;
 
   return MatchAddPrefixes(download_store_.get(),
-                          safe_browsing_util::BINURL % 2,
+                          safe_browsing::BINURL % 2,
                           prefixes,
                           prefix_hits);
 }
@@ -947,7 +949,7 @@
     return false;
 
   return MatchAddPrefixes(extension_blacklist_store_.get(),
-                          safe_browsing_util::EXTENSIONBLACKLIST % 2,
+                          safe_browsing::EXTENSIONBLACKLIST % 2,
                           prefixes,
                           prefix_hits);
 }
@@ -987,7 +989,7 @@
 bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString(
     const std::string& str) {
   std::vector<SBFullHash> hashes;
-  hashes.push_back(SBFullHashForString(str));
+  hashes.push_back(safe_browsing::SBFullHashForString(str));
   return ContainsWhitelistedHashes(SBWhitelistId::DOWNLOAD, hashes);
 }
 
@@ -1001,7 +1003,7 @@
   for (std::vector<SBFullHash>::const_iterator it = hashes.begin();
        it != hashes.end(); ++it) {
     if (std::binary_search(whitelist->first.begin(), whitelist->first.end(),
-                           *it, SBFullHashLess)) {
+                           *it, safe_browsing::SBFullHashLess)) {
       return true;
     }
   }
@@ -1011,7 +1013,7 @@
 // Helper to insert add-chunk entries.
 void SafeBrowsingDatabaseNew::InsertAddChunk(
     SafeBrowsingStore* store,
-    const safe_browsing_util::ListType list_id,
+    const safe_browsing::ListType list_id,
     const SBChunkData& chunk_data) {
   DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
   DCHECK(store);
@@ -1040,7 +1042,7 @@
 // Helper to insert sub-chunk entries.
 void SafeBrowsingDatabaseNew::InsertSubChunk(
     SafeBrowsingStore* store,
-    const safe_browsing_util::ListType list_id,
+    const safe_browsing::ListType list_id,
     const SBChunkData& chunk_data) {
   DCHECK(db_task_runner_->RunsTasksOnCurrentThread());
   DCHECK(store);
@@ -1083,8 +1085,8 @@
   const base::TimeTicks before = base::TimeTicks::Now();
 
   // TODO(shess): The caller should just pass list_id.
-  const safe_browsing_util::ListType list_id =
-      safe_browsing_util::GetListId(list_name);
+  const safe_browsing::ListType list_id =
+      safe_browsing::GetListId(list_name);
 
   SafeBrowsingStore* store = GetStore(list_id);
   if (!store) return;
@@ -1116,8 +1118,8 @@
     return;
 
   const std::string& list_name = chunk_deletes.front().list_name;
-  const safe_browsing_util::ListType list_id =
-      safe_browsing_util::GetListId(list_name);
+  const safe_browsing::ListType list_id =
+      safe_browsing::GetListId(list_name);
 
   SafeBrowsingStore* store = GetStore(list_id);
   if (!store) return;
@@ -1221,8 +1223,8 @@
   state_manager_.BeginWriteTransaction()->clear_prefix_gethash_cache();
 
   UpdateChunkRangesForLists(browse_store_.get(),
-                            safe_browsing_util::kMalwareList,
-                            safe_browsing_util::kPhishingList,
+                            safe_browsing::kMalwareList,
+                            safe_browsing::kPhishingList,
                             lists);
 
   // NOTE(shess): |download_store_| used to contain kBinHashList, which has been
@@ -1230,25 +1232,25 @@
   // of Feb 2014, so it has been removed.  Everything _should_ be resilient to
   // extra data of that sort.
   UpdateChunkRangesForList(download_store_.get(),
-                           safe_browsing_util::kBinUrlList, lists);
+                           safe_browsing::kBinUrlList, lists);
 
   UpdateChunkRangesForList(csd_whitelist_store_.get(),
-                           safe_browsing_util::kCsdWhiteList, lists);
+                           safe_browsing::kCsdWhiteList, lists);
 
   UpdateChunkRangesForList(download_whitelist_store_.get(),
-                           safe_browsing_util::kDownloadWhiteList, lists);
+                           safe_browsing::kDownloadWhiteList, lists);
 
   UpdateChunkRangesForList(inclusion_whitelist_store_.get(),
-                           safe_browsing_util::kInclusionWhitelist, lists);
+                           safe_browsing::kInclusionWhitelist, lists);
 
   UpdateChunkRangesForList(extension_blacklist_store_.get(),
-                           safe_browsing_util::kExtensionBlacklist, lists);
+                           safe_browsing::kExtensionBlacklist, lists);
 
   UpdateChunkRangesForList(ip_blacklist_store_.get(),
-                           safe_browsing_util::kIPBlacklist, lists);
+                           safe_browsing::kIPBlacklist, lists);
 
   UpdateChunkRangesForList(unwanted_software_store_.get(),
-                           safe_browsing_util::kUnwantedUrlList,
+                           safe_browsing::kUnwantedUrlList,
                            lists);
 
   db_state_manager_.reset_corruption_detected();
@@ -1702,11 +1704,13 @@
        it != full_hashes.end(); ++it) {
     new_whitelist.push_back(it->full_hash);
   }
-  std::sort(new_whitelist.begin(), new_whitelist.end(), SBFullHashLess);
+  std::sort(new_whitelist.begin(), new_whitelist.end(),
+            safe_browsing::SBFullHashLess);
 
-  SBFullHash kill_switch = SBFullHashForString(kWhitelistKillSwitchUrl);
+  SBFullHash kill_switch = safe_browsing::SBFullHashForString(
+      kWhitelistKillSwitchUrl);
   if (std::binary_search(new_whitelist.begin(), new_whitelist.end(),
-                         kill_switch, SBFullHashLess)) {
+                         kill_switch, safe_browsing::SBFullHashLess)) {
     // The kill switch is whitelisted hence we whitelist all URLs.
     state_manager_.BeginWriteTransaction()->WhitelistEverything(whitelist_id);
   } else {
@@ -1756,7 +1760,8 @@
 }
 
 bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() {
-  SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl);
+  SBFullHash malware_kill_switch = safe_browsing::SBFullHashForString(
+      kMalwareIPKillSwitchUrl);
   std::vector<SBFullHash> full_hashes;
   full_hashes.push_back(malware_kill_switch);
   return ContainsWhitelistedHashes(SBWhitelistId::CSD, full_hashes);
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.h b/chrome/browser/safe_browsing/safe_browsing_database.h
index 4d57ea3..22642a2 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.h
+++ b/chrome/browser/safe_browsing/safe_browsing_database.h
@@ -19,6 +19,7 @@
 #include "base/synchronization/lock.h"
 #include "base/time/time.h"
 #include "chrome/browser/safe_browsing/safe_browsing_store.h"
+#include "components/safe_browsing_db/util.h"
 
 namespace safe_browsing {
 class PrefixSet;
@@ -590,10 +591,10 @@
 
   // Helpers for InsertChunks().
   void InsertAddChunk(SafeBrowsingStore* store,
-                      safe_browsing_util::ListType list_id,
+                      safe_browsing::ListType list_id,
                       const SBChunkData& chunk);
   void InsertSubChunk(SafeBrowsingStore* store,
-                      safe_browsing_util::ListType list_id,
+                      safe_browsing::ListType list_id,
                       const SBChunkData& chunk);
 
   // Updates the |store| and stores the result on disk under |store_filename|.
diff --git a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
index 75e4030b..33328129 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
@@ -32,7 +32,7 @@
 const TimeDelta kCacheLifetime = TimeDelta::FromMinutes(45);
 
 SBPrefix SBPrefixForString(const std::string& str) {
-  return SBFullHashForString(str).prefix;
+  return safe_browsing::SBFullHashForString(str).prefix;
 }
 
 // Construct a full hash which has the given prefix, with the given
@@ -135,7 +135,8 @@
 // Generate an add chunk with a full hash generated from |value|.
 SBChunkData* AddChunkFullHashValue(int chunk_number,
                                    const std::string& value) {
-  return AddChunkFullHash(chunk_number, SBFullHashForString(value));
+  return AddChunkFullHash(chunk_number,
+                          safe_browsing::SBFullHashForString(value));
 }
 
 // Generate an add chunk with two full hashes.
@@ -143,8 +144,8 @@
                                    const std::string& value1,
                                    const std::string& value2) {
   const SBFullHash full_hashes[2] = {
-    SBFullHashForString(value1),
-    SBFullHashForString(value2),
+    safe_browsing::SBFullHashForString(value1),
+    safe_browsing::SBFullHashForString(value2),
   };
   return BuildChunk(chunk_number, safe_browsing::ChunkData::ADD,
                     safe_browsing::ChunkData::FULL_32B,
@@ -197,7 +198,7 @@
                                    const std::string& value,
                                    int add_chunk_number) {
   return SubChunkFullHash(chunk_number,
-                          SBFullHashForString(value),
+                          safe_browsing::SBFullHashForString(value),
                           add_chunk_number);
 }
 
@@ -351,12 +352,12 @@
   chunks.push_back(AddChunkPrefixValue(3, "www.whatever.com/malware.html"));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_LE(1U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1-3", lists[0].adds);
   EXPECT_TRUE(lists[0].subs.empty());
 
@@ -365,19 +366,19 @@
   chunks.push_back(SubChunkPrefixValue(7, "www.subbed.com/noteveil1.html", 19));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_LE(1U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1-3", lists[0].adds);
   EXPECT_EQ("7", lists[0].subs);
   if (lists.size() == 2) {
     // Old style database won't have the second entry since it creates the lists
     // when it receives an update containing that list. The filter-based
     // database has these values hard coded.
-    EXPECT_EQ(safe_browsing_util::kPhishingList, lists[1].name);
+    EXPECT_EQ(safe_browsing::kPhishingList, lists[1].name);
     EXPECT_TRUE(lists[1].adds.empty());
     EXPECT_TRUE(lists[1].subs.empty());
   }
@@ -391,15 +392,15 @@
       SubChunkPrefixValue(201, "www.phishy2.com/notevil1.html", 1999));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kPhishingList, chunks.get());
+  database_->InsertChunks(safe_browsing::kPhishingList, chunks.get());
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_LE(2U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1-3", lists[0].adds);
   EXPECT_EQ("7", lists[0].subs);
-  EXPECT_EQ(safe_browsing_util::kPhishingList, lists[1].name);
+  EXPECT_EQ(safe_browsing::kPhishingList, lists[1].name);
   EXPECT_EQ("47", lists[1].adds);
   EXPECT_EQ("200-201", lists[1].subs);
 }
@@ -412,73 +413,73 @@
 
   // Insert malware, phish, binurl and bindownload add chunks.
   chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html"));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
 
   chunks.clear();
   chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html"));
-  database_->InsertChunks(safe_browsing_util::kPhishingList, chunks.get());
+  database_->InsertChunks(safe_browsing::kPhishingList, chunks.get());
 
   chunks.clear();
   chunks.push_back(AddChunkPrefixValue(3, "www.whatever.com/download.html"));
-  database_->InsertChunks(safe_browsing_util::kBinUrlList, chunks.get());
+  database_->InsertChunks(safe_browsing::kBinUrlList, chunks.get());
 
   chunks.clear();
   chunks.push_back(AddChunkFullHashValue(5, "www.forwhitelist.com/a.html"));
-  database_->InsertChunks(safe_browsing_util::kCsdWhiteList, chunks.get());
+  database_->InsertChunks(safe_browsing::kCsdWhiteList, chunks.get());
 
   chunks.clear();
   chunks.push_back(AddChunkFullHashValue(6, "www.download.com/"));
-  database_->InsertChunks(safe_browsing_util::kDownloadWhiteList, chunks.get());
+  database_->InsertChunks(safe_browsing::kDownloadWhiteList, chunks.get());
 
   chunks.clear();
   chunks.push_back(AddChunkFullHashValue(7, "www.inclusion.com/"));
-  database_->InsertChunks(safe_browsing_util::kInclusionWhitelist,
+  database_->InsertChunks(safe_browsing::kInclusionWhitelist,
                           chunks.get());
 
   chunks.clear();
   chunks.push_back(AddChunkFullHashValue(8,
                                          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                                          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
-  database_->InsertChunks(safe_browsing_util::kExtensionBlacklist,
+  database_->InsertChunks(safe_browsing::kExtensionBlacklist,
                           chunks.get());
 
   chunks.clear();
   chunks.push_back(AddChunkHashedIpValue(10, "::ffff:192.168.1.0", 120));
-  database_->InsertChunks(safe_browsing_util::kIPBlacklist, chunks.get());
+  database_->InsertChunks(safe_browsing::kIPBlacklist, chunks.get());
 
   chunks.clear();
   chunks.push_back(AddChunkPrefixValue(11, "www.unwanted.com/software.html"));
-  database_->InsertChunks(safe_browsing_util::kUnwantedUrlList, chunks.get());
+  database_->InsertChunks(safe_browsing::kUnwantedUrlList, chunks.get());
 
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_EQ(9U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1", lists[0].adds);
   EXPECT_TRUE(lists[0].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kPhishingList, lists[1].name);
+  EXPECT_EQ(safe_browsing::kPhishingList, lists[1].name);
   EXPECT_EQ("2", lists[1].adds);
   EXPECT_TRUE(lists[1].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kBinUrlList, lists[2].name);
+  EXPECT_EQ(safe_browsing::kBinUrlList, lists[2].name);
   EXPECT_EQ("3", lists[2].adds);
   EXPECT_TRUE(lists[2].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kCsdWhiteList, lists[3].name);
+  EXPECT_EQ(safe_browsing::kCsdWhiteList, lists[3].name);
   EXPECT_EQ("5", lists[3].adds);
   EXPECT_TRUE(lists[3].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kDownloadWhiteList, lists[4].name);
+  EXPECT_EQ(safe_browsing::kDownloadWhiteList, lists[4].name);
   EXPECT_EQ("6", lists[4].adds);
   EXPECT_TRUE(lists[4].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kInclusionWhitelist, lists[5].name);
+  EXPECT_EQ(safe_browsing::kInclusionWhitelist, lists[5].name);
   EXPECT_EQ("7", lists[5].adds);
   EXPECT_TRUE(lists[5].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kExtensionBlacklist, lists[6].name);
+  EXPECT_EQ(safe_browsing::kExtensionBlacklist, lists[6].name);
   EXPECT_EQ("8", lists[6].adds);
   EXPECT_TRUE(lists[6].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kIPBlacklist, lists[7].name);
+  EXPECT_EQ(safe_browsing::kIPBlacklist, lists[7].name);
   EXPECT_EQ("10", lists[7].adds);
   EXPECT_TRUE(lists[7].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kUnwantedUrlList, lists[8].name);
+  EXPECT_EQ(safe_browsing::kUnwantedUrlList, lists[8].name);
   EXPECT_EQ("11", lists[8].adds);
   EXPECT_TRUE(lists[8].subs.empty());
 
@@ -497,11 +498,11 @@
     size_t expected_list_index;
     TestListContainsBadUrl test_list_contains_bad_url;
   } const kTestCases[] {
-    { safe_browsing_util::kMalwareList, 0U,
+    { safe_browsing::kMalwareList, 0U,
       &SafeBrowsingDatabase::ContainsBrowseUrl },
-    { safe_browsing_util::kPhishingList, 1U,
+    { safe_browsing::kPhishingList, 1U,
       &SafeBrowsingDatabase::ContainsBrowseUrl },
-    { safe_browsing_util::kUnwantedUrlList, 8U,
+    { safe_browsing::kUnwantedUrlList, 8U,
       &SafeBrowsingDatabase::ContainsUnwantedSoftwareUrl },
   };
 
@@ -757,13 +758,13 @@
                                         "www.random.com/random2.html"));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   // Add an empty ADD and SUB chunk.
   GetListsInfo(&lists);
   ASSERT_LE(1U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1,10", lists[0].adds);
   EXPECT_TRUE(lists[0].subs.empty());
 
@@ -776,12 +777,12 @@
                               NULL, 0, std::vector<int>()));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_LE(1U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1,10,19", lists[0].adds);
   EXPECT_EQ("7", lists[0].subs);
 
@@ -795,7 +796,7 @@
   chunks.push_back(AddChunkPrefixValue(22, "www.notempty.com/full2.html"));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   std::vector<SBPrefix> prefix_hits;
@@ -807,28 +808,28 @@
 
   GetListsInfo(&lists);
   ASSERT_LE(1U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1,10,19-22", lists[0].adds);
   EXPECT_EQ("7", lists[0].subs);
 
   // Handle AddDel and SubDel commands for empty chunks.
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  AddDelChunk(safe_browsing_util::kMalwareList, 21);
+  AddDelChunk(safe_browsing::kMalwareList, 21);
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_LE(1U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1,10,19-20,22", lists[0].adds);
   EXPECT_EQ("7", lists[0].subs);
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  SubDelChunk(safe_browsing_util::kMalwareList, 7);
+  SubDelChunk(safe_browsing::kMalwareList, 7);
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_LE(1U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1,10,19-20,22", lists[0].adds);
   EXPECT_TRUE(lists[0].subs.empty());
 }
@@ -843,7 +844,7 @@
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   // Cache should be cleared after updating.
@@ -851,17 +852,19 @@
       database_->GetUnsynchronizedPrefixGetHashCacheForTesting()->empty());
 
   SBFullHashResult full_hash;
-  full_hash.list_id = safe_browsing_util::MALWARE;
+  full_hash.list_id = safe_browsing::MALWARE;
 
   std::vector<SBFullHashResult> results;
   std::vector<SBPrefix> prefixes;
 
   // Add a fullhash result for each prefix.
-  full_hash.hash = SBFullHashForString("www.evil.com/phishing.html");
+  full_hash.hash =
+      safe_browsing::SBFullHashForString("www.evil.com/phishing.html");
   results.push_back(full_hash);
   prefixes.push_back(full_hash.hash.prefix);
 
-  full_hash.hash = SBFullHashForString("www.evil.com/malware.html");
+  full_hash.hash =
+      safe_browsing::SBFullHashForString("www.evil.com/malware.html");
   results.push_back(full_hash);
   prefixes.push_back(full_hash.hash.prefix);
 
@@ -882,8 +885,9 @@
       GURL("http://www.evil.com/phishing.html"), &prefix_hits, &cache_hits));
   EXPECT_TRUE(prefix_hits.empty());
   ASSERT_EQ(1U, cache_hits.size());
-  EXPECT_TRUE(SBFullHashEqual(
-      cache_hits[0].hash, SBFullHashForString("www.evil.com/phishing.html")));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+      cache_hits[0].hash,
+      safe_browsing::SBFullHashForString("www.evil.com/phishing.html")));
 
   prefix_hits.clear();
   cache_hits.clear();
@@ -893,8 +897,9 @@
       GURL("http://www.evil.com/malware.html"), &prefix_hits, &cache_hits));
   EXPECT_TRUE(prefix_hits.empty());
   ASSERT_EQ(1U, cache_hits.size());
-  EXPECT_TRUE(SBFullHashEqual(
-      cache_hits[0].hash, SBFullHashForString("www.evil.com/malware.html")));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+      cache_hits[0].hash,
+      safe_browsing::SBFullHashForString("www.evil.com/malware.html")));
 
   prefix_hits.clear();
   cache_hits.clear();
@@ -905,7 +910,7 @@
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   // This prefix should still be there, but cached fullhash should be gone.
@@ -925,7 +930,7 @@
 
   // Test that an AddDel for the original chunk removes the last cached entry.
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  AddDelChunk(safe_browsing_util::kMalwareList, 1);
+  AddDelChunk(safe_browsing::kMalwareList, 1);
   database_->UpdateFinished(true);
   EXPECT_FALSE(database_->ContainsBrowseUrl(
       GURL("http://www.evil.com/malware.html"), &prefix_hits, &cache_hits));
@@ -967,7 +972,7 @@
   // Since PopulateDatabaseForCacheTest() doesn't handle adding duplicate
   // chunks.
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  AddDelChunk(safe_browsing_util::kMalwareList, 1);
+  AddDelChunk(safe_browsing::kMalwareList, 1);
   database_->UpdateFinished(true);
 
   // Cache should be cleared after updating.
@@ -1016,7 +1021,7 @@
                                           "www.fullevil.com/bad1.html",
                                           "www.fullevil.com/bad2.html"));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   EXPECT_TRUE(database_->ContainsBrowseUrl(
@@ -1041,7 +1046,7 @@
                                          "www.fullevil.com/bad1.html",
                                          20));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   EXPECT_FALSE(database_->ContainsBrowseUrl(
@@ -1058,7 +1063,7 @@
 
   // Now test an AddDel for the remaining full add.
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  AddDelChunk(safe_browsing_util::kMalwareList, 20);
+  AddDelChunk(safe_browsing::kMalwareList, 20);
   database_->UpdateFinished(true);
 
   EXPECT_FALSE(database_->ContainsBrowseUrl(
@@ -1076,7 +1081,7 @@
   {
     ScopedVector<SBChunkData> chunks;
     chunks.push_back(AddChunkPrefixValue(21, kExampleCollision));
-    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+    database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   }
   database_->UpdateFinished(true);
 
@@ -1091,8 +1096,8 @@
   // Cache gethash response for |kExampleCollision|.
   {
     SBFullHashResult result;
-    result.hash = SBFullHashForString(kExampleCollision);
-    result.list_id = safe_browsing_util::MALWARE;
+    result.hash = safe_browsing::SBFullHashForString(kExampleCollision);
+    result.list_id = safe_browsing::MALWARE;
     database_->CacheHashResults(std::vector<SBPrefix>(1, result.hash.prefix),
                                 std::vector<SBFullHashResult>(1, result),
                                 kCacheLifetime);
@@ -1145,7 +1150,7 @@
 
     // Start an update.  The insert will fail due to corruption.
     ASSERT_TRUE(database_->UpdateStarted(&lists));
-    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+    database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
     database_->UpdateFinished(true);
 
     // Database file still exists until the corruption handler has run.
@@ -1161,7 +1166,7 @@
 
   // Run the update again successfully.
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
   EXPECT_TRUE(base::PathExists(database_filename_));
 
@@ -1179,7 +1184,7 @@
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kBinUrlList, chunks.get());
+  database_->InsertChunks(safe_browsing::kBinUrlList, chunks.get());
   database_->UpdateFinished(true);
 
   std::vector<SBPrefix> prefix_hits;
@@ -1276,13 +1281,13 @@
     // for strings.
     TestListContainsWhitelistedString test_list_contains_whitelisted_string;
   } const kTestCases[]{
-      {safe_browsing_util::kCsdWhiteList,
+      {safe_browsing::kCsdWhiteList,
        &SafeBrowsingDatabase::ContainsCsdWhitelistedUrl,
        nullptr},
-      {safe_browsing_util::kDownloadWhiteList,
+      {safe_browsing::kDownloadWhiteList,
        &SafeBrowsingDatabase::ContainsDownloadWhitelistedUrl,
        &SafeBrowsingDatabase::ContainsDownloadWhitelistedString},
-      {safe_browsing_util::kInclusionWhitelist,
+      {safe_browsing::kInclusionWhitelist,
        &SafeBrowsingDatabase::ContainsInclusionWhitelistedUrl,
        nullptr},
   };
@@ -1417,7 +1422,7 @@
             GURL(std::string("http://www.google.com/"))));
 
     // The malware kill switch is for the CSD whitelist only.
-    if (test_case.test_list_name == safe_browsing_util::kCsdWhiteList) {
+    if (test_case.test_list_name == safe_browsing::kCsdWhiteList) {
       // The CSD whitelist killswitch is not present.
       EXPECT_FALSE(database_->IsCsdWhitelistKillSwitchOn());
 
@@ -1427,7 +1432,7 @@
           15, "sb-ssl.google.com/safebrowsing/csd/killswitch_malware"));
 
       ASSERT_TRUE(database_->UpdateStarted(&lists));
-      database_->InsertChunks(safe_browsing_util::kCsdWhiteList, chunks.get());
+      database_->InsertChunks(safe_browsing::kCsdWhiteList, chunks.get());
       database_->UpdateFinished(true);
 
       EXPECT_TRUE(database_->IsMalwareIPMatchKillSwitchOn());
@@ -1446,7 +1451,7 @@
     database_->UpdateFinished(true);
 
     // Test CSD whitelist specific methods.
-    if (test_case.test_list_name == safe_browsing_util::kCsdWhiteList) {
+    if (test_case.test_list_name == safe_browsing::kCsdWhiteList) {
       // The CSD whitelist killswitch is present.
       EXPECT_TRUE(database_->IsCsdWhitelistKillSwitchOn());
       EXPECT_TRUE(database_->IsMalwareIPMatchKillSwitchOn());
@@ -1476,7 +1481,7 @@
     lists.clear();
     chunks.push_back(SubChunkFullHashValue(
         1, "sb-ssl.google.com/safebrowsing/csd/killswitch", 5));
-    if (test_case.test_list_name == safe_browsing_util::kCsdWhiteList) {
+    if (test_case.test_list_name == safe_browsing::kCsdWhiteList) {
       chunks.push_back(SubChunkFullHashValue(
           10, "sb-ssl.google.com/safebrowsing/csd/killswitch_malware", 15));
     }
@@ -1485,7 +1490,7 @@
     database_->InsertChunks(test_case.test_list_name, chunks.get());
     database_->UpdateFinished(true);
 
-    if (test_case.test_list_name == safe_browsing_util::kCsdWhiteList) {
+    if (test_case.test_list_name == safe_browsing::kCsdWhiteList) {
       EXPECT_FALSE(database_->IsMalwareIPMatchKillSwitchOn());
       EXPECT_FALSE(database_->IsCsdWhitelistKillSwitchOn());
     }
@@ -1528,12 +1533,12 @@
   // Insert the testing chunks into database.
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_LE(1U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1", lists[0].adds);
   EXPECT_TRUE(lists[0].subs.empty());
 
@@ -1544,15 +1549,15 @@
                                         "www.evil.com/phishing2.html"));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kPhishingList, chunks.get());
+  database_->InsertChunks(safe_browsing::kPhishingList, chunks.get());
   database_->UpdateFinished(true);
 
   GetListsInfo(&lists);
   ASSERT_LE(2U, lists.size());
-  EXPECT_EQ(safe_browsing_util::kMalwareList, lists[0].name);
+  EXPECT_EQ(safe_browsing::kMalwareList, lists[0].name);
   EXPECT_EQ("1", lists[0].adds);
   EXPECT_TRUE(lists[0].subs.empty());
-  EXPECT_EQ(safe_browsing_util::kPhishingList, lists[1].name);
+  EXPECT_EQ(safe_browsing::kPhishingList, lists[1].name);
   EXPECT_EQ("47", lists[1].adds);
   EXPECT_TRUE(lists[1].subs.empty());
 
@@ -1573,14 +1578,14 @@
   chunks.clear();
   chunks.push_back(SubChunkPrefixValue(4, "www.evil.com/malware1.html", 1));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   // Remove the prefix that added last.
   chunks.clear();
   chunks.push_back(SubChunkPrefixValue(5, "www.evil.com/phishing2.html", 47));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kPhishingList, chunks.get());
+  database_->InsertChunks(safe_browsing::kPhishingList, chunks.get());
   database_->UpdateFinished(true);
 
   // Verify that the database contains urls expected.
@@ -1606,7 +1611,7 @@
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
   chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html"));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   // Get an older time to reset the lastmod time for detecting whether
@@ -1623,7 +1628,7 @@
   ASSERT_TRUE(base::GetFileInfo(filename, &before_info));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
   chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html"));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
   ASSERT_TRUE(base::GetFileInfo(filename, &after_info));
   EXPECT_LT(before_info.last_modified, after_info.last_modified);
@@ -1632,7 +1637,7 @@
   ASSERT_TRUE(base::TouchFile(filename, old_last_modified, old_last_modified));
   ASSERT_TRUE(base::GetFileInfo(filename, &before_info));
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  AddDelChunk(safe_browsing_util::kMalwareList, 2);
+  AddDelChunk(safe_browsing::kMalwareList, 2);
   database_->UpdateFinished(true);
   ASSERT_TRUE(base::GetFileInfo(filename, &after_info));
   EXPECT_LT(before_info.last_modified, after_info.last_modified);
@@ -1658,7 +1663,7 @@
 
     ScopedVector<SBChunkData> chunks;
     chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html"));
-    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+    database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
     database_->UpdateFinished(true);
   }
 
@@ -1708,7 +1713,7 @@
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   {
@@ -1763,7 +1768,7 @@
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   {
@@ -1807,7 +1812,7 @@
     std::vector<SBFullHashResult> cache_results;
 
     SBFullHashResult full_hash_result;
-    full_hash_result.list_id = safe_browsing_util::MALWARE;
+    full_hash_result.list_id = safe_browsing::MALWARE;
 
     full_hash_result.hash = kFullHash1_1;
     cache_results.push_back(full_hash_result);
@@ -1827,7 +1832,8 @@
         full_hashes, &prefix_hits, &cache_hits));
     EXPECT_TRUE(prefix_hits.empty());
     ASSERT_EQ(1U, cache_hits.size());
-    EXPECT_TRUE(SBFullHashEqual(kFullHash1_1, cache_hits[0].hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kFullHash1_1, cache_hits[0].hash));
 
     // Adding kFullHash2_1 will see the existing cache hit plus the prefix hit
     // for kPrefix2.
@@ -1839,7 +1845,8 @@
     ASSERT_EQ(1U, prefix_hits.size());
     EXPECT_EQ(kPrefix2, prefix_hits[0]);
     ASSERT_EQ(1U, cache_hits.size());
-    EXPECT_TRUE(SBFullHashEqual(kFullHash1_1, cache_hits[0].hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kFullHash1_1, cache_hits[0].hash));
 
     // kFullHash1_3 also gets a cache hit.
     full_hashes.push_back(kFullHash1_3);
@@ -1850,8 +1857,10 @@
     ASSERT_EQ(1U, prefix_hits.size());
     EXPECT_EQ(kPrefix2, prefix_hits[0]);
     ASSERT_EQ(2U, cache_hits.size());
-    EXPECT_TRUE(SBFullHashEqual(kFullHash1_1, cache_hits[0].hash));
-    EXPECT_TRUE(SBFullHashEqual(kFullHash1_3, cache_hits[1].hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kFullHash1_1, cache_hits[0].hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kFullHash1_3, cache_hits[1].hash));
   }
 
   {
@@ -1863,7 +1872,8 @@
         full_hashes, &prefix_hits, &cache_hits));
     EXPECT_TRUE(prefix_hits.empty());
     ASSERT_EQ(1U, cache_hits.size());
-    EXPECT_TRUE(SBFullHashEqual(kFullHash1_3, cache_hits[0].hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kFullHash1_3, cache_hits[0].hash));
   }
 
   {
@@ -1903,7 +1913,7 @@
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   {
@@ -1938,7 +1948,7 @@
   {
     // Cache a gethash result for kFullHash1_2.
     SBFullHashResult full_hash_result;
-    full_hash_result.list_id = safe_browsing_util::MALWARE;
+    full_hash_result.list_id = safe_browsing::MALWARE;
     full_hash_result.hash = kFullHash1_2;
 
     std::vector<SBPrefix> prefixes(1, kPrefix1);
@@ -1972,7 +1982,8 @@
         full_hashes, &prefix_hits, &cache_hits));
     EXPECT_TRUE(prefix_hits.empty());
     ASSERT_EQ(1U, cache_hits.size());
-    EXPECT_TRUE(SBFullHashEqual(kFullHash1_2, cache_hits[0].hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kFullHash1_2, cache_hits[0].hash));
   }
 
   // Remove kFullHash1_1 from the database.
@@ -1980,7 +1991,7 @@
   chunks.push_back(SubChunkFullHash(11, kFullHash1_1, 1));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   // Cache should be cleared after updating.
@@ -2018,7 +2029,7 @@
   chunks.push_back(SubChunkFullHash(12, kFullHash1_2, 2));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   // Cache should be cleared after updating.
@@ -2050,7 +2061,7 @@
 
   std::vector<SBListChunkRanges> lists;
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   {
@@ -2067,7 +2078,7 @@
   chunks.push_back(AddChunkPrefix(2, kPrefix1));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   {
@@ -2087,7 +2098,7 @@
   chunks.push_back(SubChunkFullHash(11, kFullHash1_1, 1));
 
   ASSERT_TRUE(database_->UpdateStarted(&lists));
-  database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+  database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   database_->UpdateFinished(true);
 
   {
@@ -2127,7 +2138,7 @@
   // IPv4 prefix match for ::ffff:192.1.128.0/113.
   chunks.push_back(AddChunkHashedIpValue(6, "::ffff:192.1.128.0", 113));
 
-  database_->InsertChunks(safe_browsing_util::kIPBlacklist, chunks.get());
+  database_->InsertChunks(safe_browsing::kIPBlacklist, chunks.get());
   database_->UpdateFinished(true);
 
   EXPECT_FALSE(database_->ContainsMalwareIP("192.168.0.255"));
@@ -2177,7 +2188,7 @@
   {
     ScopedVector<SBChunkData> chunks;
     chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/"));
-    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+    database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   }
 
   // Add a specific fullhash.
@@ -2185,7 +2196,7 @@
   {
     ScopedVector<SBChunkData> chunks;
     chunks.push_back(AddChunkFullHashValue(2, kWhateverMalware));
-    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+    database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   }
 
   // Add a fullhash which has a prefix collision for a known url.
@@ -2197,7 +2208,7 @@
   {
     ScopedVector<SBChunkData> chunks;
     chunks.push_back(AddChunkFullHashValue(3, kExampleCollision));
-    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks.get());
+    database_->InsertChunks(safe_browsing::kMalwareList, chunks.get());
   }
 
   database_->UpdateFinished(true);
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index f1d3971a..222cb7b 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -138,8 +138,8 @@
                          std::vector<SBPrefix>* prefix_hits,
                          std::vector<SBFullHashResult>* cache_hits) override {
     cache_hits->clear();
-    return ContainsUrl(safe_browsing_util::MALWARE,
-                       safe_browsing_util::PHISH,
+    return ContainsUrl(safe_browsing::MALWARE,
+                       safe_browsing::PHISH,
                        std::vector<GURL>(1, url),
                        prefix_hits);
   }
@@ -148,8 +148,8 @@
       std::vector<SBPrefix>* prefix_hits,
       std::vector<SBFullHashResult>* cache_hits) override {
     cache_hits->clear();
-    return ContainsUrl(safe_browsing_util::UNWANTEDURL,
-                       safe_browsing_util::UNWANTEDURL,
+    return ContainsUrl(safe_browsing::UNWANTEDURL,
+                       safe_browsing::UNWANTEDURL,
                        std::vector<GURL>(1, url),
                        prefix_hits);
   }
@@ -157,8 +157,8 @@
       const std::vector<SBPrefix>& prefixes,
       std::vector<SBPrefix>* prefix_hits) override {
     bool found =
-        ContainsUrlPrefixes(safe_browsing_util::BINURL,
-                            safe_browsing_util::BINURL, prefixes, prefix_hits);
+        ContainsUrlPrefixes(safe_browsing::BINURL,
+                            safe_browsing::BINURL, prefixes, prefix_hits);
     if (!found)
       return false;
     DCHECK_LE(1U, prefix_hits->size());
@@ -424,8 +424,8 @@
                                    SBFullHashResult* full_hash) {
     std::string host;
     std::string path;
-    safe_browsing_util::CanonicalizeUrl(url, &host, &path, NULL);
-    full_hash->hash = SBFullHashForString(host + path);
+    safe_browsing::CanonicalizeUrl(url, &host, &path, NULL);
+    full_hash->hash = safe_browsing::SBFullHashForString(host + path);
     full_hash->list_id = list_id;
   }
 
@@ -601,7 +601,7 @@
 
   void GenUrlFullhashResultWithMetadata(const GURL& url,
                                         SBFullHashResult* full_hash) {
-    GenUrlFullhashResult(url, safe_browsing_util::MALWARE, full_hash);
+    GenUrlFullhashResult(url, safe_browsing::MALWARE, full_hash);
 
     safe_browsing::MalwarePatternType proto;
     switch (GetParam()) {
@@ -712,7 +712,7 @@
   // Add the img url as coming from a site serving UwS and then load the parent
   // page.
   SBFullHashResult uws_full_hash;
-  GenUrlFullhashResult(img_url, safe_browsing_util::UNWANTEDURL,
+  GenUrlFullhashResult(img_url, safe_browsing::UNWANTEDURL,
                        &uws_full_hash);
   SetupResponseForUrl(img_url, uws_full_hash);
 
@@ -727,7 +727,7 @@
   // After adding the url to safebrowsing database and getfullhash result,
   // we should see the interstitial page.
   SBFullHashResult malware_full_hash;
-  GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash);
+  GenUrlFullhashResult(url, safe_browsing::MALWARE, &malware_full_hash);
   EXPECT_CALL(observer_,
               OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1);
   EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1)
@@ -781,7 +781,7 @@
   // getfullhash result, we should not see the interstitial page since the
   // only malware was a prefetch target.
   SBFullHashResult malware_full_hash;
-  GenUrlFullhashResult(malware_url, safe_browsing_util::MALWARE,
+  GenUrlFullhashResult(malware_url, safe_browsing::MALWARE,
                        &malware_full_hash);
   SetupResponseForUrl(malware_url, malware_full_hash);
   ui_test_utils::NavigateToURL(browser(), url);
@@ -896,7 +896,7 @@
   EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
 
   SBFullHashResult full_hash_result;
-  GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
+  GenUrlFullhashResult(badbin_url, safe_browsing::BINURL,
                        &full_hash_result);
   SetupResponseForUrl(badbin_url, full_hash_result);
 
@@ -918,7 +918,7 @@
 
     SBFullHashResult full_hash_result;
     GenUrlFullhashResult(
-        bad_url, safe_browsing_util::UNWANTEDURL, &full_hash_result);
+        bad_url, safe_browsing::UNWANTEDURL, &full_hash_result);
     SetupResponseForUrl(bad_url, full_hash_result);
 
     // Now, the bad_url is not safe since it is added to download
@@ -940,7 +940,7 @@
 
     SBFullHashResult full_hash_result;
     GenUrlFullhashResult(
-        bad_url, safe_browsing_util::MALWARE, &full_hash_result);
+        bad_url, safe_browsing::MALWARE, &full_hash_result);
     SetupResponseForUrl(bad_url, full_hash_result);
 
     client->CheckBrowseUrl(bad_url);
@@ -960,7 +960,7 @@
 
     SBFullHashResult full_hash_result;
     GenUrlFullhashResult(
-        bad_url, safe_browsing_util::MALWARE, &full_hash_result);
+        bad_url, safe_browsing::MALWARE, &full_hash_result);
     SetupResponseForUrl(bad_url, full_hash_result);
 
     // Now, the bad_url is not safe since it is added to download
@@ -983,7 +983,7 @@
 
     SBFullHashResult full_hash_result;
     GenUrlFullhashResult(
-        bad_url, safe_browsing_util::UNWANTEDURL, &full_hash_result);
+        bad_url, safe_browsing::UNWANTEDURL, &full_hash_result);
     SetupResponseForUrl(bad_url, full_hash_result);
 
     client->CheckBrowseUrl(bad_url);
@@ -1007,7 +1007,7 @@
   EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
 
   SBFullHashResult full_hash_result;
-  GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
+  GenUrlFullhashResult(badbin_url, safe_browsing::BINURL,
                        &full_hash_result);
   SetupResponseForUrl(badbin_url, full_hash_result);
 
@@ -1030,7 +1030,7 @@
 
   scoped_refptr<TestSBClient> client(new TestSBClient);
   SBFullHashResult full_hash_result;
-  GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL,
+  GenUrlFullhashResult(badbin_url, safe_browsing::BINURL,
                        &full_hash_result);
   SetupResponseForUrl(badbin_url, full_hash_result);
   client->CheckDownloadUrl(badbin_urls);
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
index 768b90b..91e6fb3 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/test/test_simple_task_runner.h"
 #include "chrome/common/chrome_paths.h"
 #include "components/safe_browsing_db/prefix_set.h"
+#include "components/safe_browsing_db/util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
@@ -26,12 +27,12 @@
 const int kSubChunk1 = 2;
 const int kSubChunk2 = 4;
 
-const SBFullHash kHash1 = SBFullHashForString("one");
-const SBFullHash kHash2 = SBFullHashForString("two");
-const SBFullHash kHash3 = SBFullHashForString("three");
-const SBFullHash kHash4 = SBFullHashForString("four");
-const SBFullHash kHash5 = SBFullHashForString("five");
-const SBFullHash kHash6 = SBFullHashForString("six");
+const SBFullHash kHash1 = safe_browsing::SBFullHashForString("one");
+const SBFullHash kHash2 = safe_browsing::SBFullHashForString("two");
+const SBFullHash kHash3 = safe_browsing::SBFullHashForString("three");
+const SBFullHash kHash4 = safe_browsing::SBFullHashForString("four");
+const SBFullHash kHash5 = safe_browsing::SBFullHashForString("five");
+const SBFullHash kHash6 = safe_browsing::SBFullHashForString("six");
 
 const SBPrefix kMinSBPrefix = 0u;
 const SBPrefix kMaxSBPrefix = ~kMinSBPrefix;
@@ -194,7 +195,8 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id);
-    EXPECT_TRUE(SBFullHashEqual(kHash4, add_full_hashes_result[0].full_hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kHash4, add_full_hashes_result[0].full_hash));
   }
 }
 
@@ -279,7 +281,8 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id);
-    EXPECT_TRUE(SBFullHashEqual(kHash4, add_full_hashes_result[0].full_hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kHash4, add_full_hashes_result[0].full_hash));
   }
 
   ASSERT_TRUE(store_->BeginUpdate());
@@ -302,7 +305,8 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id);
-    EXPECT_TRUE(SBFullHashEqual(kHash4, add_full_hashes_result[0].full_hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kHash4, add_full_hashes_result[0].full_hash));
   }
 
   ASSERT_TRUE(store_->BeginUpdate());
@@ -326,7 +330,8 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id);
-    EXPECT_TRUE(SBFullHashEqual(kHash4, add_full_hashes_result[0].full_hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kHash4, add_full_hashes_result[0].full_hash));
   }
 }
 
@@ -392,7 +397,8 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk3, add_full_hashes_result[0].chunk_id);
-    EXPECT_TRUE(SBFullHashEqual(kHash6, add_full_hashes_result[0].full_hash));
+    EXPECT_TRUE(safe_browsing::SBFullHashEqual(
+        kHash6, add_full_hashes_result[0].full_hash));
   }
 
   // Expected chunks are there in another update.
@@ -665,7 +671,7 @@
   EXPECT_TRUE(store_->GetAddFullHashes(&add_hashes));
   ASSERT_EQ(1U, add_hashes.size());
   EXPECT_EQ(kAddChunk2, add_hashes[0].chunk_id);
-  EXPECT_TRUE(SBFullHashEqual(kHash4, add_hashes[0].full_hash));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(kHash4, add_hashes[0].full_hash));
 }
 
 // Test that the database handles resharding correctly, both when growing and
@@ -807,7 +813,7 @@
   EXPECT_TRUE(store_->GetAddFullHashes(&add_hashes));
   ASSERT_EQ(1U, add_hashes.size());
   EXPECT_EQ(kAddChunk1, add_hashes[0].chunk_id);
-  EXPECT_TRUE(SBFullHashEqual(kHash2, add_hashes[0].full_hash));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(kHash2, add_hashes[0].full_hash));
 
   // Attempt an update to make sure things work end-to-end.
   EXPECT_TRUE(store_->BeginUpdate());
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_store_unittest.cc
index 04751057..fb8ab175 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_unittest.cc
@@ -3,18 +3,19 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/safe_browsing/safe_browsing_store.h"
+#include "components/safe_browsing_db/util.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
 
-const SBFullHash kHash1 = SBFullHashForString("one");
-const SBFullHash kHash2 = SBFullHashForString("two");
-const SBFullHash kHash3 = SBFullHashForString("three");
-const SBFullHash kHash4 = SBFullHashForString("four");
-const SBFullHash kHash5 = SBFullHashForString("five");
-const SBFullHash kHash6 = SBFullHashForString("six");
-const SBFullHash kHash7 = SBFullHashForString("seven");
+const SBFullHash kHash1 = safe_browsing::SBFullHashForString("one");
+const SBFullHash kHash2 = safe_browsing::SBFullHashForString("two");
+const SBFullHash kHash3 = safe_browsing::SBFullHashForString("three");
+const SBFullHash kHash4 = safe_browsing::SBFullHashForString("four");
+const SBFullHash kHash5 = safe_browsing::SBFullHashForString("five");
+const SBFullHash kHash6 = safe_browsing::SBFullHashForString("six");
+const SBFullHash kHash7 = safe_browsing::SBFullHashForString("seven");
 
 const int kAddChunk1 = 1;  // Use different chunk numbers just in case.
 const int kSubChunk1 = 2;
@@ -217,9 +218,9 @@
 
   ASSERT_EQ(2U, add_hashes.size());
   EXPECT_EQ(kAddChunk5, add_hashes[0].chunk_id);
-  EXPECT_TRUE(SBFullHashEqual(kHash4, add_hashes[0].full_hash));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(kHash4, add_hashes[0].full_hash));
   EXPECT_EQ(kAddChunk6, add_hashes[1].chunk_id);
-  EXPECT_TRUE(SBFullHashEqual(kHash6, add_hashes[1].full_hash));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(kHash6, add_hashes[1].full_hash));
 
   ASSERT_EQ(1U, sub_prefixes.size());
   EXPECT_EQ(kSubChunk4, sub_prefixes[0].chunk_id);
@@ -229,7 +230,7 @@
   ASSERT_EQ(1U, sub_hashes.size());
   EXPECT_EQ(kSubChunk3, sub_hashes[0].chunk_id);
   EXPECT_EQ(kAddChunk3, sub_hashes[0].add_chunk_id);
-  EXPECT_TRUE(SBFullHashEqual(kHash7, sub_hashes[0].full_hash));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(kHash7, sub_hashes[0].full_hash));
 }
 
 // Test chunk deletions, and ordering of deletions WRT subs knocking
@@ -274,7 +275,7 @@
 
   ASSERT_EQ(1U, add_hashes.size());
   EXPECT_EQ(kAddChunk1, add_hashes[0].chunk_id);
-  EXPECT_TRUE(SBFullHashEqual(kHash6, add_hashes[0].full_hash));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(kHash6, add_hashes[0].full_hash));
 
   EXPECT_TRUE(sub_prefixes.empty());
   EXPECT_TRUE(sub_hashes.empty());
diff --git a/chrome/browser/safe_browsing/safe_browsing_util.cc b/chrome/browser/safe_browsing/safe_browsing_util.cc
index 3a5ba424..867c1aa 100644
--- a/chrome/browser/safe_browsing/safe_browsing_util.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_util.cc
@@ -4,25 +4,10 @@
 
 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
 
-#include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/safe_browsing/chunk.pb.h"
 #include "components/google/core/browser/google_util.h"
-#include "crypto/sha2.h"
-#include "net/base/escape.h"
-#include "url/gurl.h"
-#include "url/url_util.h"
-
-// SBCachedFullHashResult ------------------------------------------------------
-
-SBCachedFullHashResult::SBCachedFullHashResult() {}
-
-SBCachedFullHashResult::SBCachedFullHashResult(
-    const base::Time& in_expire_after)
-    : expire_after(in_expire_after) {}
-
-SBCachedFullHashResult::~SBCachedFullHashResult() {}
 
 // SBChunkData -----------------------------------------------------------------
 
@@ -143,343 +128,3 @@
 SBChunkDelete::SBChunkDelete() : is_sub_del(false) {}
 
 SBChunkDelete::~SBChunkDelete() {}
-
-// Utility functions -----------------------------------------------------------
-
-namespace {
-bool IsKnownList(const std::string& name) {
-  for (size_t i = 0; i < arraysize(safe_browsing_util::kAllLists); ++i) {
-    if (!strcmp(safe_browsing_util::kAllLists[i], name.c_str())) {
-      return true;
-    }
-  }
-  return false;
-}
-}  // namespace
-
-namespace safe_browsing_util {
-
-// Listnames that browser can process.
-const char kMalwareList[] = "goog-malware-shavar";
-const char kPhishingList[] = "goog-phish-shavar";
-const char kBinUrlList[] = "goog-badbinurl-shavar";
-const char kCsdWhiteList[] = "goog-csdwhite-sha256";
-const char kDownloadWhiteList[] = "goog-downloadwhite-digest256";
-const char kExtensionBlacklist[] = "goog-badcrxids-digestvar";
-const char kIPBlacklist[] = "goog-badip-digest256";
-const char kUnwantedUrlList[] = "goog-unwanted-shavar";
-const char kInclusionWhitelist[] = "goog-csdinclusionwhite-sha256";
-
-const char* kAllLists[9] = {
-    kMalwareList,
-    kPhishingList,
-    kBinUrlList,
-    kCsdWhiteList,
-    kDownloadWhiteList,
-    kExtensionBlacklist,
-    kIPBlacklist,
-    kUnwantedUrlList,
-    kInclusionWhitelist,
-};
-
-ListType GetListId(const base::StringPiece& name) {
-  ListType id;
-  if (name == safe_browsing_util::kMalwareList) {
-    id = MALWARE;
-  } else if (name == safe_browsing_util::kPhishingList) {
-    id = PHISH;
-  } else if (name == safe_browsing_util::kBinUrlList) {
-    id = BINURL;
-  } else if (name == safe_browsing_util::kCsdWhiteList) {
-    id = CSDWHITELIST;
-  } else if (name == safe_browsing_util::kDownloadWhiteList) {
-    id = DOWNLOADWHITELIST;
-  } else if (name == safe_browsing_util::kExtensionBlacklist) {
-    id = EXTENSIONBLACKLIST;
-  } else if (name == safe_browsing_util::kIPBlacklist) {
-    id = IPBLACKLIST;
-  } else if (name == safe_browsing_util::kUnwantedUrlList) {
-    id = UNWANTEDURL;
-  } else if (name == safe_browsing_util::kInclusionWhitelist) {
-    id = INCLUSIONWHITELIST;
-  } else {
-    id = INVALID;
-  }
-  return id;
-}
-
-bool GetListName(ListType list_id, std::string* list) {
-  switch (list_id) {
-    case MALWARE:
-      *list = safe_browsing_util::kMalwareList;
-      break;
-    case PHISH:
-      *list = safe_browsing_util::kPhishingList;
-      break;
-    case BINURL:
-      *list = safe_browsing_util::kBinUrlList;
-      break;
-    case CSDWHITELIST:
-      *list = safe_browsing_util::kCsdWhiteList;
-      break;
-    case DOWNLOADWHITELIST:
-      *list = safe_browsing_util::kDownloadWhiteList;
-      break;
-    case EXTENSIONBLACKLIST:
-      *list = safe_browsing_util::kExtensionBlacklist;
-      break;
-    case IPBLACKLIST:
-      *list = safe_browsing_util::kIPBlacklist;
-      break;
-    case UNWANTEDURL:
-      *list = safe_browsing_util::kUnwantedUrlList;
-      break;
-    case INCLUSIONWHITELIST:
-      *list = safe_browsing_util::kInclusionWhitelist;
-      break;
-    default:
-      return false;
-  }
-  DCHECK(IsKnownList(*list));
-  return true;
-}
-
-std::string Unescape(const std::string& url) {
-  std::string unescaped_str(url);
-  std::string old_unescaped_str;
-  const int kMaxLoopIterations = 1024;
-  int loop_var = 0;
-  do {
-    old_unescaped_str = unescaped_str;
-    unescaped_str = net::UnescapeURLComponent(
-        old_unescaped_str, net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS |
-                               net::UnescapeRule::SPACES |
-                               net::UnescapeRule::URL_SPECIAL_CHARS);
-  } while (unescaped_str != old_unescaped_str && ++loop_var <=
-           kMaxLoopIterations);
-
-  return unescaped_str;
-}
-
-std::string Escape(const std::string& url) {
-  std::string escaped_str;
-  const char* kHexString = "0123456789ABCDEF";
-  for (size_t i = 0; i < url.length(); i++) {
-    unsigned char c = static_cast<unsigned char>(url[i]);
-    if (c <= ' ' || c > '~' || c == '#' || c == '%') {
-      escaped_str.push_back('%');
-      escaped_str.push_back(kHexString[c >> 4]);
-      escaped_str.push_back(kHexString[c & 0xf]);
-    } else {
-      escaped_str.push_back(c);
-    }
-  }
-
-  return escaped_str;
-}
-
-std::string RemoveConsecutiveChars(const std::string& str, const char c) {
-  std::string output(str);
-  std::string string_to_find;
-  std::string::size_type loc = 0;
-  string_to_find.append(2, c);
-  while ((loc = output.find(string_to_find, loc)) != std::string::npos) {
-    output.erase(loc, 1);
-  }
-
-  return output;
-}
-
-// Canonicalizes url as per Google Safe Browsing Specification.
-// See section 6.1 in
-// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec.
-void CanonicalizeUrl(const GURL& url,
-                     std::string* canonicalized_hostname,
-                     std::string* canonicalized_path,
-                     std::string* canonicalized_query) {
-  DCHECK(url.is_valid());
-
-  // We only canonicalize "normal" URLs.
-  if (!url.IsStandard())
-    return;
-
-  // Following canonicalization steps are excluded since url parsing takes care
-  // of those :-
-  // 1. Remove any tab (0x09), CR (0x0d), and LF (0x0a) chars from url.
-  //    (Exclude escaped version of these chars).
-  // 2. Normalize hostname to 4 dot-seperated decimal values.
-  // 3. Lowercase hostname.
-  // 4. Resolve path sequences "/../" and "/./".
-
-  // That leaves us with the following :-
-  // 1. Remove fragment in URL.
-  GURL url_without_fragment;
-  GURL::Replacements f_replacements;
-  f_replacements.ClearRef();
-  f_replacements.ClearUsername();
-  f_replacements.ClearPassword();
-  url_without_fragment = url.ReplaceComponents(f_replacements);
-
-  // 2. Do URL unescaping until no more hex encoded characters exist.
-  std::string url_unescaped_str(Unescape(url_without_fragment.spec()));
-  url::Parsed parsed;
-  url::ParseStandardURL(url_unescaped_str.data(), url_unescaped_str.length(),
-                        &parsed);
-
-  // 3. In hostname, remove all leading and trailing dots.
-  const std::string host =
-      (parsed.host.len > 0)
-          ? url_unescaped_str.substr(parsed.host.begin, parsed.host.len)
-          : std::string();
-  std::string host_without_end_dots;
-  base::TrimString(host, ".", &host_without_end_dots);
-
-  // 4. In hostname, replace consecutive dots with a single dot.
-  std::string host_without_consecutive_dots(RemoveConsecutiveChars(
-      host_without_end_dots, '.'));
-
-  // 5. In path, replace runs of consecutive slashes with a single slash.
-  std::string path =
-      (parsed.path.len > 0)
-          ? url_unescaped_str.substr(parsed.path.begin, parsed.path.len)
-          : std::string();
-  std::string path_without_consecutive_slash(RemoveConsecutiveChars(path, '/'));
-
-  url::Replacements<char> hp_replacements;
-  hp_replacements.SetHost(
-      host_without_consecutive_dots.data(),
-      url::Component(0, host_without_consecutive_dots.length()));
-  hp_replacements.SetPath(
-      path_without_consecutive_slash.data(),
-      url::Component(0, path_without_consecutive_slash.length()));
-
-  std::string url_unescaped_with_can_hostpath;
-  url::StdStringCanonOutput output(&url_unescaped_with_can_hostpath);
-  url::Parsed temp_parsed;
-  url::ReplaceComponents(url_unescaped_str.data(),
-                         url_unescaped_str.length(),
-                         parsed,
-                         hp_replacements,
-                         NULL,
-                         &output,
-                         &temp_parsed);
-  output.Complete();
-
-  // 6. Step needed to revert escaping done in url::ReplaceComponents.
-  url_unescaped_with_can_hostpath = Unescape(url_unescaped_with_can_hostpath);
-
-  // 7. After performing all above steps, percent-escape all chars in url which
-  // are <= ASCII 32, >= 127, #, %. Escapes must be uppercase hex characters.
-  std::string escaped_canon_url_str(Escape(url_unescaped_with_can_hostpath));
-  url::Parsed final_parsed;
-  url::ParseStandardURL(escaped_canon_url_str.data(),
-                        escaped_canon_url_str.length(),
-                        &final_parsed);
-
-  if (canonicalized_hostname && final_parsed.host.len > 0) {
-    *canonicalized_hostname =
-        escaped_canon_url_str.substr(final_parsed.host.begin,
-                                     final_parsed.host.len);
-  }
-  if (canonicalized_path && final_parsed.path.len > 0) {
-    *canonicalized_path = escaped_canon_url_str.substr(final_parsed.path.begin,
-                                                       final_parsed.path.len);
-  }
-  if (canonicalized_query && final_parsed.query.len > 0) {
-    *canonicalized_query = escaped_canon_url_str.substr(
-        final_parsed.query.begin, final_parsed.query.len);
-  }
-}
-
-void GenerateHostsToCheck(const GURL& url, std::vector<std::string>* hosts) {
-  hosts->clear();
-
-  std::string canon_host;
-  CanonicalizeUrl(url, &canon_host, NULL, NULL);
-
-  const std::string host = canon_host;  // const sidesteps GCC bugs below!
-  if (host.empty())
-    return;
-
-  // Per the Safe Browsing Protocol v2 spec, we try the host, and also up to 4
-  // hostnames formed by starting with the last 5 components and successively
-  // removing the leading component.  The last component isn't examined alone,
-  // since it's the TLD or a subcomponent thereof.
-  //
-  // Note that we don't need to be clever about stopping at the "real" eTLD --
-  // the data on the server side has been filtered to ensure it will not
-  // blacklist a whole TLD, and it's not significantly slower on our side to
-  // just check too much.
-  //
-  // Also note that because we have a simple blacklist, not some sort of complex
-  // whitelist-in-blacklist or vice versa, it doesn't matter what order we check
-  // these in.
-  const size_t kMaxHostsToCheck = 4;
-  bool skipped_last_component = false;
-  for (std::string::const_reverse_iterator i(host.rbegin());
-       i != host.rend() && hosts->size() < kMaxHostsToCheck; ++i) {
-    if (*i == '.') {
-      if (skipped_last_component)
-        hosts->push_back(std::string(i.base(), host.end()));
-      else
-        skipped_last_component = true;
-    }
-  }
-  hosts->push_back(host);
-}
-
-void GeneratePathsToCheck(const GURL& url, std::vector<std::string>* paths) {
-  paths->clear();
-
-  std::string canon_path;
-  std::string canon_query;
-  CanonicalizeUrl(url, NULL, &canon_path, &canon_query);
-
-  const std::string path = canon_path;   // const sidesteps GCC bugs below!
-  const std::string query = canon_query;
-  if (path.empty())
-    return;
-
-  // Per the Safe Browsing Protocol v2 spec, we try the exact path with/without
-  // the query parameters, and also up to 4 paths formed by starting at the root
-  // and adding more path components.
-  //
-  // As with the hosts above, it doesn't matter what order we check these in.
-  const size_t kMaxPathsToCheck = 4;
-  for (std::string::const_iterator i(path.begin());
-       i != path.end() && paths->size() < kMaxPathsToCheck; ++i) {
-    if (*i == '/')
-      paths->push_back(std::string(path.begin(), i + 1));
-  }
-
-  if (!paths->empty() && paths->back() != path)
-    paths->push_back(path);
-
-  if (!query.empty())
-    paths->push_back(path + "?" + query);
-}
-
-void GeneratePatternsToCheck(const GURL& url, std::vector<std::string>* urls) {
-  std::vector<std::string> hosts, paths;
-  GenerateHostsToCheck(url, &hosts);
-  GeneratePathsToCheck(url, &paths);
-  for (size_t h = 0; h < hosts.size(); ++h) {
-    for (size_t p = 0; p < paths.size(); ++p) {
-      urls->push_back(hosts[h] + paths[p]);
-    }
-  }
-}
-
-SBFullHash StringToSBFullHash(const std::string& hash_in) {
-  DCHECK_EQ(crypto::kSHA256Length, hash_in.size());
-  SBFullHash hash_out;
-  memcpy(hash_out.full_hash, hash_in.data(), crypto::kSHA256Length);
-  return hash_out;
-}
-
-std::string SBFullHashToString(const SBFullHash& hash) {
-  DCHECK_EQ(crypto::kSHA256Length, sizeof(hash.full_hash));
-  return std::string(hash.full_hash, sizeof(hash.full_hash));
-}
-
-}  // namespace safe_browsing_util
diff --git a/chrome/browser/safe_browsing/safe_browsing_util.h b/chrome/browser/safe_browsing/safe_browsing_util.h
index b01f6a3..9cbb3cd 100644
--- a/chrome/browser/safe_browsing/safe_browsing_util.h
+++ b/chrome/browser/safe_browsing/safe_browsing_util.h
@@ -16,14 +16,12 @@
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "chrome/browser/safe_browsing/chunk_range.h"
-#include "components/safe_browsing_db/safe_browsing_db_util.h"
+#include "components/safe_browsing_db/util.h"
 
 namespace safe_browsing {
 class ChunkData;
 };
 
-class GURL;
-
 // Container for holding a chunk URL and the list it belongs to.
 struct ChunkUrl {
   std::string url;
@@ -65,24 +63,6 @@
   DISALLOW_COPY_AND_ASSIGN(SBChunkData);
 };
 
-// Used when we get a gethash response.
-struct SBFullHashResult {
-  SBFullHash hash;
-  // TODO(shess): Refactor to allow ListType here.
-  int list_id;
-  std::string metadata;
-};
-
-// Caches individual response from GETHASH request.
-struct SBCachedFullHashResult {
-  SBCachedFullHashResult();
-  explicit SBCachedFullHashResult(const base::Time& in_expire_after);
-  ~SBCachedFullHashResult();
-
-  base::Time expire_after;
-  std::vector<SBFullHashResult> full_hashes;
-};
-
 // Contains information about a list in the database.
 struct SBListChunkRanges {
   explicit SBListChunkRanges(const std::string& n);
@@ -102,81 +82,4 @@
   std::vector<ChunkRange> chunk_del;
 };
 
-// Utility functions -----------------------------------------------------------
-
-namespace safe_browsing_util {
-
-// SafeBrowsing list names.
-extern const char kMalwareList[];
-extern const char kPhishingList[];
-// Binary Download list name.
-extern const char kBinUrlList[];
-// SafeBrowsing client-side detection whitelist list name.
-extern const char kCsdWhiteList[];
-// SafeBrowsing download whitelist list name.
-extern const char kDownloadWhiteList[];
-// SafeBrowsing extension list name.
-extern const char kExtensionBlacklist[];
-// SafeBrowsing csd malware IP blacklist name.
-extern const char kIPBlacklist[];
-// SafeBrowsing unwanted URL list.
-extern const char kUnwantedUrlList[];
-// SafeBrowsing off-domain inclusion whitelist list name.
-extern const char kInclusionWhitelist[];
-
-// This array must contain all Safe Browsing lists.
-extern const char* kAllLists[9];
-
-enum ListType {
-  INVALID = -1,
-  MALWARE = 0,
-  PHISH = 1,
-  BINURL = 2,
-  // Obsolete BINHASH = 3,
-  CSDWHITELIST = 4,
-  // SafeBrowsing lists are stored in pairs.  Keep ListType 5
-  // available for a potential second list that we would store in the
-  // csd-whitelist store file.
-  DOWNLOADWHITELIST = 6,
-  // See above comment. Leave 7 available.
-  EXTENSIONBLACKLIST = 8,
-  // See above comment. Leave 9 available.
-  // Obsolete SIDEEFFECTFREEWHITELIST = 10,
-  // See above comment. Leave 11 available.
-  IPBLACKLIST = 12,
-  // See above comment.  Leave 13 available.
-  UNWANTEDURL = 14,
-  // See above comment.  Leave 15 available.
-  INCLUSIONWHITELIST = 16,
-  // See above comment.  Leave 17 available.
-};
-
-// Maps a list name to ListType.
-ListType GetListId(const base::StringPiece& name);
-
-// Maps a ListId to list name. Return false if fails.
-bool GetListName(ListType list_id, std::string* list);
-
-// Canonicalizes url as per Google Safe Browsing Specification.
-// See section 6.1 in
-// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec.
-void CanonicalizeUrl(const GURL& url, std::string* canonicalized_hostname,
-                     std::string* canonicalized_path,
-                     std::string* canonicalized_query);
-
-// Given a URL, returns all the hosts we need to check.  They are returned
-// in order of size (i.e. b.c is first, then a.b.c).
-void GenerateHostsToCheck(const GURL& url, std::vector<std::string>* hosts);
-
-// Given a URL, returns all the paths we need to check.
-void GeneratePathsToCheck(const GURL& url, std::vector<std::string>* paths);
-
-// Given a URL, returns all the patterns we need to check.
-void GeneratePatternsToCheck(const GURL& url, std::vector<std::string>* urls);
-
-SBFullHash StringToSBFullHash(const std::string& hash_in);
-std::string SBFullHashToString(const SBFullHash& hash_out);
-
-}  // namespace safe_browsing_util
-
 #endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_UTIL_H_
diff --git a/chrome/browser/safe_browsing/unverified_download_policy_unittest.cc b/chrome/browser/safe_browsing/unverified_download_policy_unittest.cc
index 94593f8b..f3590bb 100644
--- a/chrome/browser/safe_browsing/unverified_download_policy_unittest.cc
+++ b/chrome/browser/safe_browsing/unverified_download_policy_unittest.cc
@@ -45,6 +45,11 @@
 
  protected:
   ~TestSafeBrowsingService() override {}
+
+  SafeBrowsingProtocolManagerDelegate* GetProtocolManagerDelegate() override {
+    // Our FakeDatabaseManager doesn't implement this delegate.
+    return NULL;
+  }
 };
 
 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
diff --git a/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc b/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc
index 8e79336c..904a637d 100644
--- a/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc
+++ b/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc
@@ -120,13 +120,7 @@
   EXPECT_EQ(0, delegate_.num_delegate_null_called());
 }
 
-#if defined(OS_MACOSX)
-// TODO(thakis): Investigate and turn this back on, http://crbug.com/547387
-#define MAYBE_MultipleFetch DISABLED_MultipleFetch
-#else
-#define MAYBE_MultipleFetch MultipleFetch
-#endif
-IN_PROC_BROWSER_TEST_F(ImageFetcherImplBrowserTest, MAYBE_MultipleFetch) {
+IN_PROC_BROWSER_TEST_F(ImageFetcherImplBrowserTest, MultipleFetch) {
   GURL image_url(test_server_.GetURL(kTestImagePath).spec());
 
   for (int i = 0; i < 5; i++) {
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index b6d06d2..1e4140ef 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -30,7 +30,6 @@
 #include "chrome/browser/sync/glue/sync_backend_host.h"
 #include "chrome/browser/sync/glue/sync_backend_host_impl.h"
 #include "chrome/browser/sync/sync_type_preference_provider.h"
-#include "chrome/grit/generated_resources.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
 #include "components/browser_sync/common/browser_sync_switches.h"
 #include "components/history/core/browser/typed_url_data_type_controller.h"
@@ -41,6 +40,7 @@
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/signin/core/browser/signin_metrics.h"
+#include "components/strings/grit/components_strings.h"
 #include "components/sync_driver/backend_migrator.h"
 #include "components/sync_driver/change_processor.h"
 #include "components/sync_driver/data_type_controller.h"
diff --git a/chrome/browser/sync/profile_sync_service_unittest.cc b/chrome/browser/sync/profile_sync_service_unittest.cc
index ab874472..34c3d1b 100644
--- a/chrome/browser/sync/profile_sync_service_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_unittest.cc
@@ -27,7 +27,6 @@
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -38,6 +37,7 @@
 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/signin/core/browser/signin_manager.h"
+#include "components/strings/grit/components_strings.h"
 #include "components/sync_driver/data_type_manager.h"
 #include "components/sync_driver/data_type_manager_observer.h"
 #include "components/sync_driver/fake_data_type_controller.h"
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index d6a2493..4f6a754 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -164,7 +164,7 @@
 #include "components/search/search.h"
 #include "components/sessions/core/session_types.h"
 #include "components/sessions/core/tab_restore_service.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/ui/zoom/zoom_controller.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
diff --git a/chrome/browser/ui/cocoa/simple_message_box_mac.mm b/chrome/browser/ui/cocoa/simple_message_box_mac.mm
index 4193a64..508b84f 100644
--- a/chrome/browser/ui/cocoa/simple_message_box_mac.mm
+++ b/chrome/browser/ui/cocoa/simple_message_box_mac.mm
@@ -9,7 +9,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/browser/ui/simple_message_box_internal.h"
 #include "chrome/grit/generated_resources.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
 namespace chrome {
diff --git a/chrome/browser/ui/extensions/extension_message_bubble_factory.cc b/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
index d898377..192fefc5 100644
--- a/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
+++ b/chrome/browser/ui/extensions/extension_message_bubble_factory.cc
@@ -8,13 +8,13 @@
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
 #include "base/metrics/field_trial.h"
-#include "chrome/browser/extensions/dev_mode_bubble_controller.h"
+#include "chrome/browser/extensions/dev_mode_bubble_delegate.h"
 #include "chrome/browser/extensions/extension_message_bubble_controller.h"
 #include "chrome/browser/extensions/install_verifier.h"
-#include "chrome/browser/extensions/proxy_overridden_bubble_controller.h"
-#include "chrome/browser/extensions/settings_api_bubble_controller.h"
+#include "chrome/browser/extensions/proxy_overridden_bubble_delegate.h"
+#include "chrome/browser/extensions/settings_api_bubble_delegate.h"
 #include "chrome/browser/extensions/settings_api_helpers.h"
-#include "chrome/browser/extensions/suspicious_extension_bubble_controller.h"
+#include "chrome/browser/extensions/suspicious_extension_bubble_delegate.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/channel_info.h"
@@ -108,8 +108,10 @@
   bool is_initial_check = profiles_evaluated.count(original_profile) == 0;
   profiles_evaluated.insert(original_profile);
 
+  scoped_ptr<extensions::ExtensionMessageBubbleController> controller;
+
   if (g_override_for_testing == OVERRIDE_DISABLED)
-    return scoped_ptr<extensions::ExtensionMessageBubbleController>();
+    return controller.Pass();
 
   // The list of suspicious extensions takes priority over the dev mode bubble
   // and the settings API bubble, since that needs to be shown as soon as we
@@ -120,8 +122,11 @@
   // the dev mode extensions on the next startup/next window that opens. That
   // way, we're not too spammy with the bubbles.
   if (EnableSuspiciousExtensionsBubble()) {
-    scoped_ptr<extensions::SuspiciousExtensionBubbleController> controller(
-        new extensions::SuspiciousExtensionBubbleController(browser_));
+    controller.reset(
+        new extensions::ExtensionMessageBubbleController(
+            new extensions::SuspiciousExtensionBubbleDelegate(
+                browser_->profile()),
+            browser_));
     if (controller->ShouldShow())
       return controller.Pass();
   }
@@ -129,29 +134,37 @@
   if (EnableSettingsApiBubble()) {
     // No use showing this if it's not the startup of the profile.
     if (is_initial_check) {
-      scoped_ptr<extensions::SettingsApiBubbleController> controller(
-          new extensions::SettingsApiBubbleController(
-              browser_, extensions::BUBBLE_TYPE_STARTUP_PAGES));
+      controller.reset(new extensions::ExtensionMessageBubbleController(
+              new extensions::SettingsApiBubbleDelegate(
+                  browser_->profile(), extensions::BUBBLE_TYPE_STARTUP_PAGES),
+                  browser_));
       if (controller->ShouldShow())
         return controller.Pass();
     }
   }
 
   if (EnableProxyOverrideBubble()) {
-    scoped_ptr<extensions::ProxyOverriddenBubbleController> controller(
-        new extensions::ProxyOverriddenBubbleController(browser_));
+    controller.reset(
+        new extensions::ExtensionMessageBubbleController(
+            new extensions::ProxyOverriddenBubbleDelegate(
+                browser_->profile()),
+            browser_));
     if (controller->ShouldShow())
       return controller.Pass();
   }
 
   if (EnableDevModeBubble()) {
-    scoped_ptr<extensions::DevModeBubbleController> controller(
-        new extensions::DevModeBubbleController(browser_));
+    controller.reset(
+        new extensions::ExtensionMessageBubbleController(
+            new extensions::DevModeBubbleDelegate(
+                browser_->profile()),
+            browser_));
     if (controller->ShouldShow())
       return controller.Pass();
   }
 
-  return scoped_ptr<extensions::ExtensionMessageBubbleController>();
+  controller.reset();
+  return controller.Pass();
 }
 
 // static
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc
index 553b5db8..88b827a 100644
--- a/chrome/browser/ui/startup/bad_flags_prompt.cc
+++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -20,7 +20,7 @@
 #include "components/infobars/core/simple_alert_infobar_delegate.h"
 #include "components/invalidation/impl/invalidation_switches.h"
 #include "components/nacl/common/nacl_switches.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "components/translate/core/common/translate_switches.h"
 #include "content/public/common/content_switches.h"
 #include "extensions/common/switches.h"
diff --git a/chrome/browser/ui/startup/default_browser_prompt_win.cc b/chrome/browser/ui/startup/default_browser_prompt_win.cc
index 8ba18a2..d2d01ce1 100644
--- a/chrome/browser/ui/startup/default_browser_prompt_win.cc
+++ b/chrome/browser/ui/startup/default_browser_prompt_win.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/webui/set_as_default_browser_ui.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.cc b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
index 3bebd07b..1c309e4 100644
--- a/chrome/browser/ui/views/exclusive_access_bubble_views.cc
+++ b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
@@ -28,7 +28,6 @@
 #include "ui/views/controls/link.h"
 #include "ui/views/controls/link_listener.h"
 #include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/grid_layout.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 #include "url/gurl.h"
@@ -53,9 +52,6 @@
   ButtonView(views::ButtonListener* listener, int between_button_spacing);
   ~ButtonView() override;
 
-  // Returns an empty size when the view is not visible.
-  gfx::Size GetPreferredSize() const override;
-
   views::LabelButton* accept_button() const { return accept_button_; }
   views::LabelButton* deny_button() const { return deny_button_; }
 
@@ -85,10 +81,6 @@
 ButtonView::~ButtonView() {
 }
 
-gfx::Size ButtonView::GetPreferredSize() const {
-  return visible() ? views::View::GetPreferredSize() : gfx::Size();
-}
-
 }  // namespace
 
 class ExclusiveAccessBubbleViews::ExclusiveAccessView
@@ -178,13 +170,10 @@
 
   exit_instruction_ =
       new views::Label(bubble_->GetInstructionText(), medium_font_list);
-  exit_instruction_->set_collapse_when_hidden(true);
-
   exit_instruction_->SetEnabledColor(foreground_color);
   exit_instruction_->SetBackgroundColor(background_color);
 
   link_ = new views::Link();
-  link_->set_collapse_when_hidden(true);
   link_->SetFocusable(false);
 #if defined(OS_CHROMEOS)
   // On CrOS, the link text doesn't change, since it doesn't show the shortcut.
@@ -199,34 +188,16 @@
 
   button_view_ = new ButtonView(this, kPaddingPx);
 
-  views::GridLayout* layout = new views::GridLayout(this);
-  views::ColumnSet* columns = layout->AddColumnSet(0);
-  if (!ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) {
-    // In the simplified UI, do not show the message label, only the exit
-    // instruction.
-    columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0,
-                       views::GridLayout::USE_PREF, 0, 0);
-    columns->AddPaddingColumn(1, kMiddlePaddingPx);
-  }
-  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0,
-                     views::GridLayout::USE_PREF, 0, 0);
-  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0,
-                     views::GridLayout::USE_PREF, 0, 0);
-  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0,
-                     views::GridLayout::USE_PREF, 0, 0);
-
-  layout->StartRow(0, 0);
   if (!ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled()) {
     DCHECK(message_label_);
-    layout->AddView(message_label_);
+    AddChildView(message_label_);
   }
-  layout->AddView(button_view_);
-  layout->AddView(exit_instruction_);
-  layout->AddView(link_);
+  AddChildView(button_view_);
+  AddChildView(exit_instruction_);
+  AddChildView(link_);
 
-  gfx::Insets padding(kPaddingPx, kPaddingPx, kPaddingPx, kPaddingPx);
-  padding += GetInsets();
-  layout->SetInsets(padding);
+  views::BoxLayout* layout = new views::BoxLayout(
+      views::BoxLayout::kHorizontal, kPaddingPx, kPaddingPx, kMiddlePaddingPx);
   SetLayoutManager(layout);
 
   UpdateContent(url, bubble_type);
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc
index 802c4427..ca30393 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -9,6 +9,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/infobar_container_delegate.h"
+#include "chrome/browser/ui/views/bar_control_button.h"
 #include "chrome/browser/ui/views/infobars/infobar_background.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/infobars/core/infobar_delegate.h"
@@ -60,6 +61,10 @@
                             : ui::ResourceBundle::MediumFont);
 }
 
+SkColor GetInfobarTextColor() {
+  return SK_ColorBLACK;
+}
+
 }  // namespace
 
 
@@ -90,7 +95,7 @@
   views::Label* label = new views::Label(text, GetFontList());
   label->SizeToPreferredSize();
   label->SetBackgroundColor(background()->get_color());
-  label->SetEnabledColor(SK_ColorBLACK);
+  label->SetEnabledColor(GetInfobarTextColor());
   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   return label;
 }
@@ -131,8 +136,8 @@
 
     button->SetBorder(button_border.Pass());
     button->set_animate_on_state_change(false);
-    button->SetTextColor(views::Button::STATE_NORMAL, SK_ColorBLACK);
-    button->SetTextColor(views::Button::STATE_HOVERED, SK_ColorBLACK);
+    button->SetTextColor(views::Button::STATE_NORMAL, GetInfobarTextColor());
+    button->SetTextColor(views::Button::STATE_HOVERED, GetInfobarTextColor());
     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
     button->SetFontList(rb.GetFontList(ui::ResourceBundle::MediumFont));
   }
@@ -222,13 +227,14 @@
       AddChildView(icon_);
     }
 
-    close_button_ = new views::ImageButton(this);
-
     if (ui::MaterialDesignController::IsModeMaterial()) {
-      gfx::ImageSkia image = gfx::CreateVectorIcon(gfx::VectorIconId::BAR_CLOSE,
-                                                   16, gfx::kChromeIconGrey);
-      close_button_->SetImage(views::CustomButton::STATE_NORMAL, &image);
+      BarControlButton* close = new BarControlButton(this);
+      close->SetIcon(gfx::VectorIconId::BAR_CLOSE,
+                     base::Bind(&GetInfobarTextColor));
+      close->set_request_focus_on_press(false);
+      close_button_ = close;
     } else {
+      close_button_ = new views::ImageButton(this);
       ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
       close_button_->SetImage(views::CustomButton::STATE_NORMAL,
                               rb.GetImageNamed(IDR_CLOSE_1).ToImageSkia());
diff --git a/chrome/browser/ui/views/settings_api_bubble_helper_views.cc b/chrome/browser/ui/views/settings_api_bubble_helper_views.cc
index b1eb80e..f26f2941 100644
--- a/chrome/browser/ui/views/settings_api_bubble_helper_views.cc
+++ b/chrome/browser/ui/views/settings_api_bubble_helper_views.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/ui/views/settings_api_bubble_helper_views.h"
 
-#include "chrome/browser/extensions/ntp_overridden_bubble_controller.h"
-#include "chrome/browser/extensions/settings_api_bubble_controller.h"
+#include "chrome/browser/extensions/ntp_overridden_bubble_delegate.h"
+#include "chrome/browser/extensions/settings_api_bubble_delegate.h"
 #include "chrome/browser/extensions/settings_api_helpers.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -28,8 +28,9 @@
                            Browser* browser,
                            views::View* anchor_view,
                            views::BubbleBorder::Arrow arrow) {
-  scoped_ptr<SettingsApiBubbleController> settings_api_bubble(
-      new SettingsApiBubbleController(browser, type));
+  scoped_ptr<ExtensionMessageBubbleController> settings_api_bubble(
+      new ExtensionMessageBubbleController(
+          new SettingsApiBubbleDelegate(browser->profile(), type), browser));
   if (!settings_api_bubble->ShouldShow())
     return;
 
@@ -98,8 +99,9 @@
   if (ntp_url != active_url)
     return;  // Not being overridden by an extension.
 
-  scoped_ptr<NtpOverriddenBubbleController> ntp_overridden_bubble(
-      new NtpOverriddenBubbleController(browser));
+  scoped_ptr<ExtensionMessageBubbleController> ntp_overridden_bubble(
+      new ExtensionMessageBubbleController(
+          new NtpOverriddenBubbleDelegate(browser->profile()), browser));
   if (!ntp_overridden_bubble->ShouldShow())
     return;
 
diff --git a/chrome/browser/ui/views/simple_message_box_views.cc b/chrome/browser/ui/views/simple_message_box_views.cc
index 1732509b..50433760 100644
--- a/chrome/browser/ui/views/simple_message_box_views.cc
+++ b/chrome/browser/ui/views/simple_message_box_views.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/ui/simple_message_box_internal.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/constrained_window/constrained_window_views.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/native_widget_types.h"
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
index 932d7a9..e039325 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -13,7 +13,6 @@
 #include "chromeos/dbus/fake_cras_audio_client.h"
 #include "chromeos/dbus/fake_power_manager_client.h"
 #include "content/public/browser/web_ui.h"
-#include "device/bluetooth/bluetooth_device_chromeos.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
 #include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
diff --git a/chrome/browser/ui/webui/downloads_dom_handler.h b/chrome/browser/ui/webui/downloads_dom_handler.h
index 495d32c..bf30369 100644
--- a/chrome/browser/ui/webui/downloads_dom_handler.h
+++ b/chrome/browser/ui/webui/downloads_dom_handler.h
@@ -45,9 +45,6 @@
   void OnDownloadRemoved(content::DownloadManager* manager,
                          content::DownloadItem* download_item) override;
 
-  // Callback for the "onPageLoaded" message.
-  void OnPageLoaded(const base::ListValue* args);
-
   // Callback for the "getDownloads" message.
   void HandleGetDownloads(const base::ListValue* args);
 
diff --git a/chrome/browser/ui/webui/foreign_session_handler.cc b/chrome/browser/ui/webui/foreign_session_handler.cc
index d64efe67..3fbf4fe9 100644
--- a/chrome/browser/ui/webui/foreign_session_handler.cc
+++ b/chrome/browser/ui/webui/foreign_session_handler.cc
@@ -26,8 +26,8 @@
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
-#include "chrome/grit/generated_resources.h"
 #include "components/pref_registry/pref_registry_syncable.h"
+#include "components/strings/grit/components_strings.h"
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.cc b/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.cc
index 97c125d4..403cbbf 100644
--- a/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.cc
+++ b/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.cc
@@ -506,7 +506,7 @@
   if (!file)
     return;
 
-  std::vector<content::DownloadItem*> downloads;
+  DownloadVector downloads;
   downloads.push_back(file);
   RemoveDownloads(downloads);
 }
@@ -516,7 +516,7 @@
   if (removals_.empty())
     return;
 
-  const std::set<uint32> last_removed_ids = removals_.back();
+  const IdSet last_removed_ids = removals_.back();
   removals_.pop_back();
 
   for (auto id : last_removed_ids) {
@@ -549,7 +549,7 @@
 
   CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CLEAR_ALL);
 
-  std::vector<content::DownloadItem*> downloads;
+  DownloadVector downloads;
   if (GetMainNotifierManager())
     GetMainNotifierManager()->GetAllDownloads(&downloads);
   if (GetOriginalNotifierManager())
@@ -557,9 +557,8 @@
   RemoveDownloads(downloads);
 }
 
-void MdDownloadsDOMHandler::RemoveDownloads(
-    const std::vector<content::DownloadItem*>& to_remove) {
-  std::set<uint32> ids;
+void MdDownloadsDOMHandler::RemoveDownloads(const DownloadVector& to_remove) {
+  IdSet ids;
 
   for (auto* download : to_remove) {
     DownloadItemModel item_model(download);
@@ -618,7 +617,7 @@
 
 void MdDownloadsDOMHandler::FinalizeRemovals() {
   while (!removals_.empty()) {
-    const std::set<uint32> remove = removals_.back();
+    const IdSet remove = removals_.back();
     removals_.pop_back();
 
     for (const auto id : remove) {
diff --git a/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.h b/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.h
index c129ba8..0aee5da13 100644
--- a/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.h
+++ b/chrome/browser/ui/webui/md_downloads/md_downloads_dom_handler.h
@@ -46,9 +46,6 @@
   void OnDownloadRemoved(content::DownloadManager* manager,
                          content::DownloadItem* download_item) override;
 
-  // Callback for the "onPageLoaded" message.
-  void OnPageLoaded(const base::ListValue* args);
-
   // Callback for the "getDownloads" message.
   void HandleGetDownloads(const base::ListValue* args);
 
@@ -108,9 +105,8 @@
   void FinalizeRemovals();
 
  private:
-  // Shorthand for |observing_items_|, which tracks all items that this is
-  // observing so that RemoveObserver will be called for all of them.
-  typedef std::set<content::DownloadItem*> DownloadSet;
+  using IdSet = std::set<uint32>;
+  using DownloadVector = std::vector<content::DownloadItem*>;
 
   // Convenience method to call |main_notifier_->GetManager()| while
   // null-checking |main_notifier_|.
@@ -146,7 +142,7 @@
   content::DownloadItem* GetDownloadById(uint32 id);
 
   // Remove all downloads in |to_remove| with the ability to undo removal later.
-  void RemoveDownloads(const std::vector<content::DownloadItem*>& to_remove);
+  void RemoveDownloads(const DownloadVector& to_remove);
 
   // Weak reference to the DownloadManager this class was constructed with. You
   // should probably be using use Get{Main,Original}NotifierManager() instead.
@@ -163,13 +159,13 @@
   scoped_ptr<AllDownloadItemNotifier> original_notifier_;
 
   // IDs of downloads to remove when this handler gets deleted.
-  std::vector<std::set<uint32>> removals_;
+  std::vector<IdSet> removals_;
 
   // Whether a call to SendCurrentDownloads() is currently scheduled.
   bool update_scheduled_;
 
   // IDs of new downloads that the page doesn't know about yet.
-  std::set<uint32> new_downloads_;
+  IdSet new_downloads_;
 
   base::WeakPtrFactory<MdDownloadsDOMHandler> weak_ptr_factory_;
 
diff --git a/chrome/browser/ui/webui/md_downloads/md_downloads_ui.cc b/chrome/browser/ui/webui/md_downloads/md_downloads_ui.cc
index bc93a55..9003ff3 100644
--- a/chrome/browser/ui/webui/md_downloads/md_downloads_ui.cc
+++ b/chrome/browser/ui/webui/md_downloads/md_downloads_ui.cc
@@ -110,6 +110,7 @@
   source->AddResourcePath("constants.js", IDR_MD_DOWNLOADS_CONSTANTS_JS);
   source->AddResourcePath("crisper.js", IDR_MD_DOWNLOADS_CRISPER_JS);
   source->AddResourcePath("dev.html", IDR_MD_DOWNLOADS_DOWNLOADS_HTML);
+  source->AddResourcePath("downloads.js", IDR_MD_DOWNLOADS_DOWNLOADS_JS);
   source->AddResourcePath("item.css", IDR_MD_DOWNLOADS_ITEM_CSS);
   source->AddResourcePath("item.html", IDR_MD_DOWNLOADS_ITEM_HTML);
   source->AddResourcePath("item.js", IDR_MD_DOWNLOADS_ITEM_JS);
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 7400c3e..cfd46cc 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -154,19 +154,23 @@
           'product_name': '<(mac_product_name) Helper',
           'mac_bundle': 1,
           'dependencies': [
-            'chrome_dll',
+            'chrome_dll_dependency_shim',
             'infoplist_strings_tool',
+            'common_constants.gyp:version_header',
+          ],
+          'defines': [
+            'HELPER_EXECUTABLE'
           ],
           'sources': [
-            # chrome_exe_main_mac.cc's main() is the entry point for
+            # chrome_exe_main_mac.c's main() is the entry point for
             # the "chrome" (browser app) target.  All it does is jump
             # to chrome_dll's ChromeMain.  This is appropriate for
             # helper processes too, because the logic to discriminate
             # between process types at run time is actually directed
             # by the --type command line argument processed by
-            # ChromeMain.  Sharing chrome_exe_main_mac.cc with the
+            # ChromeMain.  Sharing chrome_exe_main_mac.c with the
             # browser app will suffice for now.
-            'app/chrome_exe_main_mac.cc',
+            'app/chrome_exe_main_mac.c',
             'app/helper-Info.plist',
           ],
           # TODO(mark): Come up with a fancier way to do this.  It should only
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 60fecc6..43257cf 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -102,6 +102,8 @@
       'browser/android/contextualsearch/contextual_search_manager.h',
       'browser/android/contextualsearch/contextual_search_tab_helper.cc',
       'browser/android/contextualsearch/contextual_search_tab_helper.h',
+      'browser/android/contextualsearch/resolved_search_term.cc',
+      'browser/android/contextualsearch/resolved_search_term.h',
       'browser/android/cookies/cookies_fetcher.cc',
       'browser/android/cookies/cookies_fetcher.h',
       'browser/android/data_usage/external_data_use_observer.cc',
@@ -3117,7 +3119,7 @@
         '../components/components.gyp:ssl_errors',
         '../components/components.gyp:suggestions',
         '../components/components.gyp:signin_core_browser',
-        '../components/components.gyp:startup_metric_utils_browser',
+        '../components/components.gyp:startup_metric_utils',
         '../components/components.gyp:sync_bookmarks',
         '../components/components.gyp:sync_driver',
         '../components/components.gyp:sync_sessions',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index 01db708..aadff083 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -19,8 +19,8 @@
         'browser/chromeos/accessibility/spoken_feedback_event_rewriter.h',
         'browser/chromeos/app_mode/app_launch_utils.cc',
         'browser/chromeos/app_mode/app_launch_utils.h',
-        'browser/chromeos/app_mode/app_session_lifetime.cc',
-        'browser/chromeos/app_mode/app_session_lifetime.h',
+        'browser/chromeos/app_mode/app_session.cc',
+        'browser/chromeos/app_mode/app_session.h',
         'browser/chromeos/app_mode/certificate_manager_dialog.cc',
         'browser/chromeos/app_mode/certificate_manager_dialog.h',
         'browser/chromeos/app_mode/kiosk_app_data.cc',
@@ -45,6 +45,9 @@
         'browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h',
         'browser/chromeos/app_mode/kiosk_profile_loader.cc',
         'browser/chromeos/app_mode/kiosk_profile_loader.h',
+        'browser/chromeos/app_mode/kiosk_session_plugin_handler.cc',
+        'browser/chromeos/app_mode/kiosk_session_plugin_handler.h',
+        'browser/chromeos/app_mode/kiosk_session_plugin_handler_delegate.h',
         'browser/chromeos/app_mode/startup_app_launcher.cc',
         'browser/chromeos/app_mode/startup_app_launcher.h',
         'browser/chromeos/attestation/attestation_ca_client.cc',
@@ -344,8 +347,6 @@
         'browser/chromeos/input_method/input_method_delegate_impl.h',
         'browser/chromeos/input_method/input_method_engine.cc',
         'browser/chromeos/input_method/input_method_engine.h',
-        'browser/chromeos/input_method/input_method_engine_interface.cc',
-        'browser/chromeos/input_method/input_method_engine_interface.h',
         'browser/chromeos/input_method/input_method_manager_impl.cc',
         'browser/chromeos/input_method/input_method_manager_impl.h',
         'browser/chromeos/input_method/input_method_persistence.cc',
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index f9ae0c9..377d132 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -621,8 +621,8 @@
       'browser/extensions/crx_installer.h',
       'browser/extensions/data_deleter.cc',
       'browser/extensions/data_deleter.h',
-      'browser/extensions/dev_mode_bubble_controller.cc',
-      'browser/extensions/dev_mode_bubble_controller.h',
+      'browser/extensions/dev_mode_bubble_delegate.cc',
+      'browser/extensions/dev_mode_bubble_delegate.h',
       'browser/extensions/devtools_util.cc',
       'browser/extensions/devtools_util.h',
       'browser/extensions/display_info_provider_chromeos.cc',
@@ -795,8 +795,8 @@
       'browser/extensions/menu_manager_factory.h',
       'browser/extensions/navigation_observer.cc',
       'browser/extensions/navigation_observer.h',
-      'browser/extensions/ntp_overridden_bubble_controller.cc',
-      'browser/extensions/ntp_overridden_bubble_controller.h',
+      'browser/extensions/ntp_overridden_bubble_delegate.cc',
+      'browser/extensions/ntp_overridden_bubble_delegate.h',
       'browser/extensions/pack_extension_job.cc',
       'browser/extensions/pack_extension_job.h',
       'browser/extensions/path_util.cc',
@@ -811,12 +811,12 @@
       'browser/extensions/permissions_updater.h',
       'browser/extensions/plugin_manager.cc',
       'browser/extensions/plugin_manager.h',
-      'browser/extensions/proxy_overridden_bubble_controller.cc',
-      'browser/extensions/proxy_overridden_bubble_controller.h',
+      'browser/extensions/proxy_overridden_bubble_delegate.cc',
+      'browser/extensions/proxy_overridden_bubble_delegate.h',
       'browser/extensions/scripting_permissions_modifier.cc',
       'browser/extensions/scripting_permissions_modifier.h',
-      'browser/extensions/settings_api_bubble_controller.cc',
-      'browser/extensions/settings_api_bubble_controller.h',
+      'browser/extensions/settings_api_bubble_delegate.cc',
+      'browser/extensions/settings_api_bubble_delegate.h',
       'browser/extensions/settings_api_helpers.cc',
       'browser/extensions/settings_api_helpers.h',
       'browser/extensions/shared_module_service.cc',
@@ -833,8 +833,8 @@
       'browser/extensions/startup_helper.h',
       'browser/extensions/state_store_notification_observer.cc',
       'browser/extensions/state_store_notification_observer.h',
-      'browser/extensions/suspicious_extension_bubble_controller.cc',
-      'browser/extensions/suspicious_extension_bubble_controller.h',
+      'browser/extensions/suspicious_extension_bubble_delegate.cc',
+      'browser/extensions/suspicious_extension_bubble_delegate.h',
       'browser/extensions/sync_bundle.cc',
       'browser/extensions/sync_bundle.h',
       'browser/extensions/tab_helper.cc',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 9b5c97c..dd9e066 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -27,17 +27,6 @@
       'common/chrome_content_client_ios.mm',
       'common/chrome_result_codes.h',
       'common/chrome_utility_messages.h',
-      'common/chrome_utility_printing_messages.h',
-      'common/cloud_print/cloud_print_cdd_conversion.cc',
-      'common/cloud_print/cloud_print_cdd_conversion.h',
-      'common/cloud_print/cloud_print_class_mac.h',
-      'common/cloud_print/cloud_print_class_mac.mm',
-      'common/cloud_print/cloud_print_constants.cc',
-      'common/cloud_print/cloud_print_constants.h',
-      'common/cloud_print/cloud_print_helpers.cc',
-      'common/cloud_print/cloud_print_helpers.h',
-      'common/cloud_print/cloud_print_proxy_info.cc',
-      'common/cloud_print/cloud_print_proxy_info.h',
       'common/common_message_generator.cc',
       'common/common_message_generator.h',
       'common/common_param_traits.cc',
@@ -200,6 +189,19 @@
       'common/extensions/sync_helper.cc',
       'common/extensions/sync_helper.h',
     ],
+    'chrome_common_printing_sources': [
+      'common/chrome_utility_printing_messages.h',
+      'common/cloud_print/cloud_print_cdd_conversion.cc',
+      'common/cloud_print/cloud_print_cdd_conversion.h',
+      'common/cloud_print/cloud_print_class_mac.h',
+      'common/cloud_print/cloud_print_class_mac.mm',
+      'common/cloud_print/cloud_print_constants.cc',
+      'common/cloud_print/cloud_print_constants.h',
+      'common/cloud_print/cloud_print_helpers.cc',
+      'common/cloud_print/cloud_print_helpers.h',
+      'common/cloud_print/cloud_print_proxy_info.cc',
+      'common/cloud_print/cloud_print_proxy_info.h',
+    ],
     'chrome_common_extensions_chromeos_sources': [
       'common/extensions/api/file_browser_handlers/file_browser_handler.cc',
       'common/extensions/api/file_browser_handlers/file_browser_handler.h',
@@ -460,6 +462,8 @@
           ],
         }],
         ['enable_basic_printing==1 or enable_print_preview==1', {
+          'sources': [ '<@(chrome_common_printing_sources)' ],
+
           'dependencies': [
             '<(DEPTH)/components/components.gyp:printing_common',
             '<(DEPTH)/printing/printing.gyp:printing',
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi
index b0422e4..b2a2081 100644
--- a/chrome/chrome_dll.gypi
+++ b/chrome/chrome_dll.gypi
@@ -3,6 +3,35 @@
 # found in the LICENSE file.
 {
   'conditions': [
+    # Dummy target to allow chrome to require chrome_dll to build
+    # without actually linking to the library
+    ['OS=="mac"', {
+      'targets': [
+        {
+          'target_name': 'chrome_dll_dependency_shim',
+          'type': 'executable',
+          'dependencies': [
+            'chrome_dll',
+          ],
+          # In release, we end up with a strip step that is unhappy if there is
+          # no binary. Rather than check in a new file for this hack, just
+          # generate a source file on the fly.
+          'actions': [
+            {
+              'action_name': 'generate_stub_main',
+              'process_outputs_as_sources': 1,
+              'inputs': [],
+              'outputs': [ '<(INTERMEDIATE_DIR)/dummy_main.c' ],
+              'action': [
+                'bash', '-c',
+                'echo "int main() { return 0; }" > <(INTERMEDIATE_DIR)/dummy_main.c'
+              ],
+            },
+          ],
+        },
+      ],
+     },
+    ],
     ['OS=="mac" or OS=="win"', {
       'targets': [
         {
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi
index 9cab3368..94f56ef 100644
--- a/chrome/chrome_exe.gypi
+++ b/chrome/chrome_exe.gypi
@@ -46,6 +46,7 @@
       # GN version: //chrome:chrome_initial
       'target_name': 'chrome_initial',
       'type': 'executable',
+      'dependencies' : [ '../chrome/common_constants.gyp:version_header', ],
       # Name the exe chrome.exe, not chrome_initial.exe.
       'product_name': 'chrome',
       'mac_bundle': 1,
@@ -60,7 +61,7 @@
         '<(DEPTH)/content/public/common/content_switches.cc',
         'app/chrome_exe_load_config_win.cc',
         'app/chrome_exe_main_aura.cc',
-        'app/chrome_exe_main_mac.cc',
+        'app/chrome_exe_main_mac.c',
         'app/chrome_exe_main_win.cc',
         'app/chrome_exe_resource.h',
         'app/chrome_watcher_client_win.cc',
@@ -270,7 +271,7 @@
             'infoplist_strings_tool',
             # On Mac, make sure we've built chrome_dll, which contains all of
             # the library code with Chromium functionality.
-            'chrome_dll',
+            'chrome_dll_dependency_shim',
           ],
           'mac_bundle_resources': [
             'app/theme/<(branding_path_component)/mac/app.icns',
@@ -365,7 +366,7 @@
             # "chrome" etc.; should we try to extract from there instead?
           ],
           'dependencies': [
-            '../components/components.gyp:startup_metric_utils_browser',
+            '../components/components.gyp:startup_metric_utils',
             'chrome_resources.gyp:packed_extra_resources',
             'chrome_resources.gyp:packed_resources',
             # Copy Flash Player files to PRODUCT_DIR if applicable. Let the .gyp
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index cfca4bb..ee1800f 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -251,6 +251,7 @@
         '../components/components.gyp:network_hints_renderer',
         '../components/components.gyp:omnibox_common',
         '../components/components.gyp:error_page_renderer',
+        '../components/components.gyp:startup_metric_utils',
         '../components/components.gyp:page_load_metrics_renderer',
         '../components/components.gyp:password_manager_content_renderer',
         '../components/components.gyp:plugins_renderer',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 46b0955e..e56355dc 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -61,6 +61,7 @@
       'browser/apps/guest_view/app_view_browsertest.cc',
       'browser/apps/guest_view/extension_view/extension_view_browsertest.cc',
       'browser/apps/guest_view/web_view_browsertest.cc',
+      'browser/apps/service_worker_browsertest.cc',
       'browser/apps/window_controls_browsertest.cc',
       'browser/autocomplete/autocomplete_browsertest.cc',
       'browser/autofill/autofill_browsertest.cc',
@@ -959,6 +960,7 @@
       'test/data/webui/certificate_viewer_dialog_test.js',
       'test/data/webui/chrome_send_browsertest.js',
       'test/data/webui/history_browsertest.js',
+      'test/data/webui/md_downloads/downloads_browsertest.js',
       'test/data/webui/mock4js_browsertest.js',
       'test/data/webui/net_internals/bandwidth_view.js',
       'test/data/webui/net_internals/chromeos_view.js',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 2c9bf8de..5f3f0f4d 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -995,7 +995,6 @@
       'browser/safe_browsing/safe_browsing_database_unittest.cc',
       'browser/safe_browsing/safe_browsing_store_file_unittest.cc',
       'browser/safe_browsing/safe_browsing_store_unittest.cc',
-      'browser/safe_browsing/safe_browsing_util_unittest.cc',
       'browser/safe_browsing/sandboxed_dmg_analyzer_mac_unittest.cc',
       'browser/safe_browsing/sandboxed_zip_analyzer_unittest.cc',
       'browser/safe_browsing/signature_evaluator_mac_unittest.cc',
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index 01becfb..50a8661 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -179,6 +179,9 @@
 
   # Printing.
   if (enable_basic_printing || enable_print_preview) {
+    sources +=
+        rebase_path(gypi_values.chrome_common_printing_sources, ".", "//chrome")
+
     public_deps += [
       "//components/printing/common",
       "//printing",
diff --git a/chrome/common/all_messages.h b/chrome/common/all_messages.h
index 44bdf1c..5ed2dce 100644
--- a/chrome/common/all_messages.h
+++ b/chrome/common/all_messages.h
@@ -18,7 +18,7 @@
 #if defined(ENABLE_PRINTING)
 // TODO(dgn) remove from here when all the code using these messages is removed
 // from /chrome. (crbug.com/311308, crbug.com/450822)
-#include "components/printing/common/print_messages.h"
+#include "components/printing/common/print_messages.h"  // nogncheck
 #endif
 
 #if !defined(DISABLE_NACL)
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc
index 06e262f..414b3f60 100644
--- a/chrome/common/crash_keys.cc
+++ b/chrome/common/crash_keys.cc
@@ -146,6 +146,19 @@
     { kBug464926CrashKey, kSmallSize },
     { kViewCount, kSmallSize },
     { kZeroEncodeDetails, kSmallSize },
+
+    // Temporary for http://crbug.com/369661
+    { "pageid", kSmallSize },
+    { "navuniqueid", kSmallSize },
+    { "oldindex", kSmallSize },
+    { "newindex", kSmallSize },
+    { "lastcommittedindex", kSmallSize },
+    { "oldurl", kLargeSize },
+    { "newurl", kLargeSize },
+    { "updatedvalue", kLargeSize },
+    { "oldvalue", kLargeSize },
+    { "newvalue", kLargeSize },
+    // End http://crbug.com/369661
   };
 
   // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
index 518d9c4..0b62b2fd 100644
--- a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
+++ b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
@@ -537,10 +537,6 @@
                 "href": "/apps/faq"
               },
               {
-                "title": "Google Groups",
-                "href": "https://groups.google.com/a/chromium.org/forum/#!forum/chromium-apps"
-              },
-              {
                 "title": "Stack Overflow",
                 "href": "http://stackoverflow.com/questions/tagged/google-chrome-app"
               }
@@ -1072,8 +1068,8 @@
                 "href": "/webstore/faq"
               },
               {
-                "title": "Google Groups",
-                "href": "https://groups.google.com/a/chromium.org/forum/#!forum/chromium-apps"
+                "title": "Stack Overflow",
+                "href": "http://stackoverflow.com/questions/tagged/google-chrome-app"
               },
               {
                 "title": "Articles",
diff --git a/chrome/installer/mac/sign_app.sh.in b/chrome/installer/mac/sign_app.sh.in
index 21256567a..7cd44203 100644
--- a/chrome/installer/mac/sign_app.sh.in
+++ b/chrome/installer/mac/sign_app.sh.in
@@ -50,9 +50,11 @@
 and certificate leaf = H\"85cee8254216185620ddc8851c7a9fc4dfe120ef\"\
 "
 
+enforcement_flags="restrict"
+
 codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" \
     "${browser_app}" --resource-rules "${browser_app_rules}" \
-    -r="${requirement_string}"
+    -r="${requirement_string}" --options "${enforcement_flags}"
 
 # Show the signature.
 codesign --display -r- -vvvvvv "${browser_app}"
diff --git a/chrome/installer/mac/sign_versioned_dir.sh.in b/chrome/installer/mac/sign_versioned_dir.sh.in
index e134742..f68b7aa 100644
--- a/chrome/installer/mac/sign_versioned_dir.sh.in
+++ b/chrome/installer/mac/sign_versioned_dir.sh.in
@@ -48,10 +48,12 @@
 and certificate leaf = H\"85cee8254216185620ddc8851c7a9fc4dfe120ef\"\
 "
 
+enforcement_flags="restrict"
+
 codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" \
     "${crashpad_handler}" \
     -r="designated => identifier \"crashpad_handler\" \
-${requirement_suffix}"
+${requirement_suffix}" --options "${enforcement_flags}"
 codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" \
     "${framework}" \
     -r="designated => identifier \"com.google.Chrome.framework\" \
@@ -59,7 +61,7 @@
 codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" \
     "${helper_app}" \
     -r="designated => identifier \"com.google.Chrome.helper\" \
-${requirement_suffix}"
+${requirement_suffix}" --options "${enforcement_flags}"
 
 # Verify everything. Don't use --deep on the framework because Keystone's
 # signature is in a transitional state (radar 18474911).
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
index 13b806d7..e041627 100644
--- a/chrome/renderer/BUILD.gn
+++ b/chrome/renderer/BUILD.gn
@@ -49,6 +49,7 @@
     "//components/password_manager/content/renderer",
     "//components/plugins/renderer",
     "//components/printing/renderer",
+    "//components/startup_metric_utils",
     "//components/translate/content/renderer",
     "//components/translate/core/common",
     "//components/translate/core/language_detection",
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 3d815b12..2ce1501 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -125,8 +125,10 @@
 #endif
 
 #if defined(ENABLE_PRINTING)
+#include "chrome/common/chrome_content_client.h"
 #include "chrome/renderer/printing/chrome_print_web_view_helper_delegate.h"
 #include "components/printing/renderer/print_web_view_helper.h"
+#include "printing/print_settings.h"
 #endif
 
 #if defined(ENABLE_PRINT_PREVIEW)
@@ -355,6 +357,9 @@
   for (size_t i = 0; i < arraysize(kPredefinedAllowedCompositorOrigins); ++i)
     allowed_compositor_origins_.insert(kPredefinedAllowedCompositorOrigins[i]);
 #endif
+#if defined(ENABLE_PRINTING)
+  printing::SetAgent(GetUserAgent());
+#endif
 }
 
 ChromeContentRendererClient::~ChromeContentRendererClient() {
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc
index 56dbf991..f82d232 100644
--- a/chrome/renderer/chrome_render_frame_observer.cc
+++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -33,7 +33,6 @@
 #include "third_party/WebKit/public/web/WebElement.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/jpeg_codec.h"
@@ -44,7 +43,6 @@
 using blink::WebElement;
 using blink::WebLocalFrame;
 using blink::WebNode;
-using blink::WebNodeList;
 using blink::WebString;
 using content::SSLStatus;
 using content::RenderFrame;
diff --git a/chrome/renderer/extensions/webstore_bindings.cc b/chrome/renderer/extensions/webstore_bindings.cc
index 88c9c710..e6fcc8f 100644
--- a/chrome/renderer/extensions/webstore_bindings.cc
+++ b/chrome/renderer/extensions/webstore_bindings.cc
@@ -16,7 +16,6 @@
 #include "third_party/WebKit/public/web/WebElement.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
 #include "url/gurl.h"
 #include "v8/include/v8.h"
@@ -24,7 +23,6 @@
 using blink::WebDocument;
 using blink::WebElement;
 using blink::WebNode;
-using blink::WebNodeList;
 using blink::WebUserGestureIndicator;
 
 namespace extensions {
@@ -127,9 +125,8 @@
 
   GURL webstore_base_url =
       GURL(extension_urls::GetWebstoreItemDetailURLPrefix());
-  WebNodeList children = head.childNodes();
-  for (unsigned i = 0; i < children.length(); ++i) {
-    WebNode child = children.item(i);
+  for (WebNode child = head.firstChild(); !child.isNull();
+       child = child.nextSibling()) {
     if (!child.isElementNode())
       continue;
     WebElement elem = child.to<WebElement>();
diff --git a/chrome/renderer/web_apps.cc b/chrome/renderer/web_apps.cc
index 98d1afa2..4dfe6fc 100644
--- a/chrome/renderer/web_apps.cc
+++ b/chrome/renderer/web_apps.cc
@@ -23,7 +23,6 @@
 #include "third_party/WebKit/public/web/WebElement.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "ui/gfx/geometry/size.h"
 #include "url/gurl.h"
 
@@ -31,7 +30,6 @@
 using blink::WebElement;
 using blink::WebFrame;
 using blink::WebNode;
-using blink::WebNodeList;
 using blink::WebString;
 
 namespace web_apps {
@@ -131,9 +129,8 @@
     return;
 
   GURL document_url = document.url();
-  WebNodeList children = head.childNodes();
-  for (unsigned i = 0; i < children.length(); ++i) {
-    WebNode child = children.item(i);
+  for (WebNode child = head.firstChild(); !child.isNull();
+      child = child.nextSibling()) {
     if (!child.isElementNode())
       continue;
     WebElement elem = child.to<WebElement>();
diff --git a/chrome/test/data/android/contextualsearch/tap_test.html b/chrome/test/data/android/contextualsearch/tap_test.html
index 4a10e80..ad7598c3 100644
--- a/chrome/test/data/android/contextualsearch/tap_test.html
+++ b/chrome/test/data/android/contextualsearch/tap_test.html
@@ -25,6 +25,8 @@
   <!-- These three spans should be close to each other so that taps from one to
        to the next are within our "near" threshold. -->
   <div><span id="search">Search</span> <span id="term">Term</span> <span id="resolution">Resolution</span></div>
+  <!-- This element is used to trigger language translation. -->
+  <div><span id="german">Deutsche</span></div>
   <form action="demo_form.asp">
     <label for="male">Male</label>
     <input type="radio" name="sex" id="male" value="male"><br>
diff --git a/chrome/test/data/extensions/platform_apps/service_worker/app.html b/chrome/test/data/extensions/platform_apps/service_worker/app.html
new file mode 100644
index 0000000..f711ff6d
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/service_worker/app.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<!--
+ * Copyright 2015 The Chromium Authors. All rights reserved.  Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+<script src="app.js"></script>
diff --git a/chrome/test/data/extensions/platform_apps/service_worker/app.js b/chrome/test/data/extensions/platform_apps/service_worker/app.js
new file mode 100644
index 0000000..184e420
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/service_worker/app.js
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+chrome.test.runTests([
+  function registerAndPostMessage() {
+    navigator.serviceWorker.register('sw.js').then(function() {
+      return navigator.serviceWorker.ready;
+    }).then(function(r) {
+      var mc = new MessageChannel();
+      mc.port1.onmessage = function(e) {
+        mc.port1.onmessage = null;
+        if (e.data && e.data.response === 'pong') {
+          chrome.test.succeed();
+        } else {
+          chrome.test.fail();
+        }
+      };
+      var sw = r.active;
+      sw.postMessage({request: 'ping'}, [mc.port2]);
+    }).catch(function(err) {
+      chrome.test.fail();
+    });
+  }
+]);
diff --git a/chrome/test/data/extensions/platform_apps/service_worker/background.js b/chrome/test/data/extensions/platform_apps/service_worker/background.js
new file mode 100644
index 0000000..a41fafd
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/service_worker/background.js
@@ -0,0 +1,7 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+chrome.app.runtime.onLaunched.addListener(function() {
+  chrome.app.window.create('app.html', {});
+});
diff --git a/chrome/test/data/extensions/platform_apps/service_worker/manifest.json b/chrome/test/data/extensions/platform_apps/service_worker/manifest.json
new file mode 100644
index 0000000..797a624
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/service_worker/manifest.json
@@ -0,0 +1,11 @@
+{
+  "name": "Platform App ServiceWorker test",
+  "description": "Platform App ServiceWorker test.",
+  "version": "1",
+  "manifest_version": 2,
+  "app": {
+    "background": {
+      "scripts": ["background.js"]
+    }
+  }
+}
diff --git a/chrome/test/data/extensions/platform_apps/service_worker/sw.js b/chrome/test/data/extensions/platform_apps/service_worker/sw.js
new file mode 100644
index 0000000..832f34fa
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/service_worker/sw.js
@@ -0,0 +1,9 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+self.onmessage = function(e) {
+  if (e.data && e.data.request === 'ping') {
+    e.ports[0].postMessage({response: 'pong'});
+  }
+};
diff --git a/chrome/test/data/nacl/ppapi/ppp_instance/ppapi_ppp_instance.cc b/chrome/test/data/nacl/ppapi/ppp_instance/ppapi_ppp_instance.cc
index 9ad5a47..d9e1f80 100644
--- a/chrome/test/data/nacl/ppapi/ppp_instance/ppapi_ppp_instance.cc
+++ b/chrome/test/data/nacl/ppapi/ppp_instance/ppapi_ppp_instance.cc
@@ -45,13 +45,14 @@
 
   PP_Rect clip;
   PPBView()->GetClipRect(view, &clip);
-  EXPECT(clip.point.x == 0 && clip.point.y == 0);
+  EXPECT(clip.point.x == 0 && clip.point.y == -1);
 
   // These are based on embed dimensions.
   PP_Rect position;
   PPBView()->GetRect(view, &position);
+  fprintf(stderr, "clip.size.height: %d\n", clip.size.height);
   EXPECT(position.size.width == 15 && clip.size.width == 15);
-  EXPECT(position.size.height == 20 && clip.size.height == 20);
+  EXPECT(position.size.height == 20 && clip.size.height == 23);
 
   TEST_PASSED;
 }
diff --git a/chrome/test/data/webui/md_downloads/downloads_browsertest.js b/chrome/test/data/webui/md_downloads/downloads_browsertest.js
new file mode 100644
index 0000000..09bb056
--- /dev/null
+++ b/chrome/test/data/webui/md_downloads/downloads_browsertest.js
@@ -0,0 +1,38 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/** @fileoverview Tests for the Material Design downloads page. */
+
+/** @const {string} Path to source root. */
+var ROOT_PATH = '../../../../../';
+
+// Polymer BrowserTest fixture.
+GEN_INCLUDE(
+    [ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
+
+/**
+ * @constructor
+ * @extends {PolymerTest}
+*/
+function DownloadsBrowserTest() {}
+
+DownloadsBrowserTest.prototype = {
+  __proto__: PolymerTest.prototype,
+
+  /** @override */
+  browsePreload: 'chrome://downloads/manager.html',
+
+  /** @override */
+  commandLineSwitches: [{switchName: 'enable-md-downloads'}],
+
+  /** @override */
+  extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([
+    'layout_tests.js',
+  ]),
+};
+
+TEST_F('DownloadsBrowserTest', 'layoutTests', function() {
+  downloads.layout_tests.registerTests();
+  mocha.run();
+});
diff --git a/chrome/test/data/webui/md_downloads/layout_tests.js b/chrome/test/data/webui/md_downloads/layout_tests.js
new file mode 100644
index 0000000..7c09cf6
--- /dev/null
+++ b/chrome/test/data/webui/md_downloads/layout_tests.js
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('downloads.layout_tests', function() {
+  function registerTests() {
+    suite('LayoutTests', function() {
+      /** @type {!downloads.Manager} */
+      var manager;
+
+      setup(function() {
+        PolymerTest.clearBody();
+        manager = document.createElement('downloads-manager');
+        document.body.appendChild(manager);
+      });
+
+      test('long URLs ellide', function() {
+        manager.updateAll_([{
+          file_name: 'file name',
+          state: downloads.States.COMPLETE,
+          url: 'a'.repeat(10000),
+        }]);
+
+        Polymer.dom.flush();
+
+        var item = manager.$$('downloads-item');
+        assertLT(item.$$('#url').offsetWidth, item.offsetWidth);
+      });
+    });
+  }
+
+  return {
+    registerTests: registerTests,
+  };
+});
diff --git a/chrome/test/ppapi/ppapi_filechooser_browsertest.cc b/chrome/test/ppapi/ppapi_filechooser_browsertest.cc
index 54c04b5..99ebf15 100644
--- a/chrome/test/ppapi/ppapi_filechooser_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_filechooser_browsertest.cc
@@ -143,6 +143,11 @@
 
  protected:
   ~TestSafeBrowsingService() override {}
+
+  SafeBrowsingProtocolManagerDelegate* GetProtocolManagerDelegate() override {
+    // Our FakeDatabaseManager doesn't implement this delegate.
+    return NULL;
+  }
 };
 
 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
index f2169e3..306af8af 100644
--- a/chromecast/BUILD.gn
+++ b/chromecast/BUILD.gn
@@ -2,10 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/features.gni")
+import("//build/config/locales.gni")
+import("//build/config/ui.gni")
 import("//chromecast/build/tests/cast_test.gni")
 import("//chromecast/chromecast.gni")
-import("//build/config/features.gni")
-import("//build/config/ui.gni")
 import("//tools/grit/repack.gni")
 import("//ui/ozone/ozone.gni")
 
@@ -149,8 +150,8 @@
 
 source_set("cast_shell_common") {
   deps = [
-    # TODO(slan): add ":cast_locales_pak" (b/22959691)
     ":cast_shell_pak",
+    ":chromecast_locales_pak",
     "//chromecast/app",
     "//chromecast/browser",
     "//chromecast/common",
@@ -237,3 +238,46 @@
     }
   }
 }
+
+# GYP target: chromecast_locales.gyp:chromecast_locales_pak
+action("chromecast_locales_pak") {
+  script = "//chromecast/tools/build/chromecast_repack_locales.py"
+
+  # .pak resources in |grit_out_dir| with the same suffix are packed into a
+  # single resource and placed in |locales_dir|. The original .pak resources
+  # are generated by this target's dependencies.
+  grit_out_dir = "$root_gen_dir/chromecast_strings"
+  locales_dir = "$root_out_dir/chromecast_locales"
+
+  sources = []
+  outputs = []
+
+  # |locales| is an array of suffixes declared in //build/config/locals.gni.
+  foreach(locale, locales) {
+    sources += [ "$grit_out_dir/chromecast_settings_$locale.pak" ]
+    outputs += [ "$locales_dir/$locale.pak" ]
+  }
+  deps = [
+    "//chromecast/app:chromecast_settings",
+  ]
+
+  # Include string resources for internal builds.
+  if (chromecast_branding != "public") {
+    foreach(locale, locales) {
+      sources += [ "$grit_out_dir/app_strings_$locale.pak" ]
+    }
+    deps += [ "//chromecast/internal/webui:chromecast_app_strings" ]
+  }
+
+  # This script only accepts the following values for branding:
+  assert(chromecast_branding == "public" || chromecast_branding == "internal" ||
+         chromecast_branding == "google")
+  args = [
+           "-b",
+           "$chromecast_branding",
+           "-g",
+           rebase_path("$root_gen_dir/chromecast_strings"),
+           "-x",
+           rebase_path("$root_out_dir/chromecast_locales"),
+         ] + locales
+}
diff --git a/chromecast/app/BUILD.gn b/chromecast/app/BUILD.gn
index 3f27c1d0..c3746d4 100644
--- a/chromecast/app/BUILD.gn
+++ b/chromecast/app/BUILD.gn
@@ -74,10 +74,11 @@
   ]
 }
 
+# GYP target: chromecast_locales.gyp:chromecast_settings
 grit("chromecast_settings") {
   source = "//chromecast/app/resources/chromecast_settings.grd"
-
   resource_ids = "//chromecast/app/resources/resource_ids"
+  output_dir = "$root_gen_dir/chromecast_strings"
 
   outputs = [
     "grit/chromecast_settings.h",
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc
index e8f7e59..98aae10 100644
--- a/chromecast/media/audio/cast_audio_output_stream.cc
+++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -98,7 +98,7 @@
   void Close() {
     DCHECK(thread_checker_.CalledOnValidThread());
 
-    if (backend_)
+    if (backend_ && !first_start_)  // Only stop the backend if it was started.
       backend_->Stop();
     backend_.reset();
     backend_task_runner_.reset();
diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
index 608d9b6..6d2f734 100644
--- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc
+++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
@@ -129,21 +129,22 @@
     return true;
   }
   bool Start(int64_t start_pts) override {
-    DCHECK(state_ == kStateStopped);
+    EXPECT_EQ(kStateStopped, state_);
     state_ = kStateRunning;
     return true;
   }
   bool Stop() override {
+    EXPECT_TRUE(state_ == kStateRunning || state_ == kStatePaused);
     state_ = kStateStopped;
     return true;
   }
   bool Pause() override {
-    DCHECK(state_ == kStateRunning);
+    EXPECT_EQ(kStateRunning, state_);
     state_ = kStatePaused;
     return true;
   }
   bool Resume() override {
-    DCHECK(state_ == kStatePaused);
+    EXPECT_EQ(kStatePaused, state_);
     state_ = kStateRunning;
     return true;
   }
@@ -639,6 +640,13 @@
   CloseStream(stream);
 }
 
+TEST_F(CastAudioOutputStreamTest, CloseWithoutStart) {
+  ::media::AudioOutputStream* stream = CreateStream();
+  ASSERT_TRUE(stream);
+  ASSERT_TRUE(OpenStream(stream));
+  CloseStream(stream);
+}
+
 }  // namespace
 }  // namespace media
 }  // namespace chromecast
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 9ab9baf..eb49db3d 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-7611.0.0
\ No newline at end of file
+7615.0.0
\ No newline at end of file
diff --git a/chromeos/dbus/fake_session_manager_client.cc b/chromeos/dbus/fake_session_manager_client.cc
index 89261ea..77e8b37 100644
--- a/chromeos/dbus/fake_session_manager_client.cc
+++ b/chromeos/dbus/fake_session_manager_client.cc
@@ -151,6 +151,23 @@
       FROM_HERE, base::Bind(callback, server_backed_state_keys_));
 }
 
+void FakeSessionManagerClient::CheckArcAvailability(
+    const ArcCallback& callback) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                base::Bind(callback, false));
+}
+
+void FakeSessionManagerClient::StartArcInstance(const std::string& socket_path,
+                                                const ArcCallback& callback) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                base::Bind(callback, false));
+}
+
+void FakeSessionManagerClient::StopArcInstance(const ArcCallback& callback) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                base::Bind(callback, false));
+}
+
 const std::string& FakeSessionManagerClient::device_policy() const {
   return device_policy_;
 }
diff --git a/chromeos/dbus/fake_session_manager_client.h b/chromeos/dbus/fake_session_manager_client.h
index e2ff7cc..2a96cd3 100644
--- a/chromeos/dbus/fake_session_manager_client.h
+++ b/chromeos/dbus/fake_session_manager_client.h
@@ -62,6 +62,11 @@
                        const std::vector<std::string>& flags) override;
   void GetServerBackedStateKeys(const StateKeysCallback& callback) override;
 
+  void CheckArcAvailability(const ArcCallback& callback) override;
+  void StartArcInstance(const std::string& socket_path,
+                        const ArcCallback& callback) override;
+  void StopArcInstance(const ArcCallback& callback) override;
+
   const std::string& device_policy() const;
   void set_device_policy(const std::string& policy_blob);
 
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc
index ca7c6a5b..c50841f 100644
--- a/chromeos/dbus/fake_shill_manager_client.cc
+++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -37,6 +37,9 @@
 int s_tdls_busy_count = 0;
 int s_extra_wifi_networks = 0;
 
+// For testing dynamic WEP networks (uses wifi2).
+bool s_dynamic_wep = false;
+
 // Used to compare values for finding entries to erase in a ListValue.
 // (ListValue only implements a const_iterator version of Find).
 struct ValueEquals {
@@ -694,15 +697,23 @@
     profiles->AddService(shared_profile, kWifi1Path);
 
     const std::string kWifi2Path = "/service/wifi2";
-    services->AddService(kWifi2Path,
-                         "wifi2_PSK_guid",
-                         "wifi2_PSK" /* name */,
-                         shill::kTypeWifi,
-                         shill::kStateIdle,
-                         add_to_visible);
-    services->SetServiceProperty(kWifi2Path,
-                                 shill::kSecurityClassProperty,
-                                 base::StringValue(shill::kSecurityPsk));
+    services->AddService(kWifi2Path, "wifi2_guid",
+                         s_dynamic_wep ? "wifi2_WEP" : "wifi2_PSK" /* name */,
+                         shill::kTypeWifi, shill::kStateIdle, add_to_visible);
+    if (s_dynamic_wep) {
+      services->SetServiceProperty(kWifi2Path, shill::kSecurityClassProperty,
+                                   base::StringValue(shill::kSecurityWep));
+      services->SetServiceProperty(
+          kWifi2Path, shill::kEapKeyMgmtProperty,
+          base::StringValue(shill::kKeyManagementIEEE8021X));
+      services->SetServiceProperty(kWifi2Path, shill::kEapMethodProperty,
+                                   base::StringValue(shill::kEapMethodPEAP));
+      services->SetServiceProperty(kWifi2Path, shill::kEapIdentityProperty,
+                                   base::StringValue("John Doe"));
+    } else {
+      services->SetServiceProperty(kWifi2Path, shill::kSecurityClassProperty,
+                                   base::StringValue(shill::kSecurityPsk));
+    }
     services->SetServiceProperty(
         kWifi2Path, shill::kSignalStrengthProperty, base::FundamentalValue(80));
     profiles->AddService(shared_profile, kWifi2Path);
@@ -1111,6 +1122,9 @@
     // "home", "roaming", or "required"
     roaming_state_ = arg1;
     return true;
+  } else if (arg0 == "dynamic_wep" && arg1 == "1") {
+    s_dynamic_wep = true;
+    return true;
   }
   return SetInitialNetworkState(arg0, arg1);
 }
diff --git a/chromeos/dbus/mock_session_manager_client.h b/chromeos/dbus/mock_session_manager_client.h
index 17f0caf..aec901a 100644
--- a/chromeos/dbus/mock_session_manager_client.h
+++ b/chromeos/dbus/mock_session_manager_client.h
@@ -57,6 +57,9 @@
                void(const std::string&,
                     const std::vector<std::string>&));
   MOCK_METHOD1(GetServerBackedStateKeys, void(const StateKeysCallback&));
+  MOCK_METHOD1(CheckArcAvailability, void(const ArcCallback&));
+  MOCK_METHOD2(StartArcInstance, void(const std::string&, const ArcCallback&));
+  MOCK_METHOD1(StopArcInstance, void(const ArcCallback&));
 };
 
 }  // namespace chromeos
diff --git a/chromeos/dbus/session_manager_client.cc b/chromeos/dbus/session_manager_client.cc
index 36a4e28c..f3431c5 100644
--- a/chromeos/dbus/session_manager_client.cc
+++ b/chromeos/dbus/session_manager_client.cc
@@ -331,6 +331,41 @@
                    callback));
   }
 
+  void CheckArcAvailability(const ArcCallback& callback) override {
+    dbus::MethodCall method_call(
+        login_manager::kSessionManagerInterface,
+        login_manager::kSessionManagerCheckArcAvailability);
+
+    session_manager_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::Bind(&SessionManagerClientImpl::OnCheckArcAvailability,
+                   weak_ptr_factory_.GetWeakPtr(), callback));
+  }
+
+  void StartArcInstance(const std::string& socket_path,
+                        const ArcCallback& callback) override {
+    dbus::MethodCall method_call(
+        login_manager::kSessionManagerInterface,
+        login_manager::kSessionManagerStartArcInstance);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendString(socket_path);
+    session_manager_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::Bind(&SessionManagerClientImpl::OnArcMethod,
+                   weak_ptr_factory_.GetWeakPtr(),
+                   login_manager::kSessionManagerStartArcInstance, callback));
+  }
+
+  void StopArcInstance(const ArcCallback& callback) override {
+    dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
+                                 login_manager::kSessionManagerStopArcInstance);
+    session_manager_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::Bind(&SessionManagerClientImpl::OnArcMethod,
+                   weak_ptr_factory_.GetWeakPtr(),
+                   login_manager::kSessionManagerStartArcInstance, callback));
+  }
+
  protected:
   void Init(dbus::Bus* bus) override {
     session_manager_proxy_ = bus->GetObjectProxy(
@@ -631,6 +666,37 @@
       callback.Run(state_keys);
   }
 
+  // Called when kSessionManagerCheckArcAvailability method is complete.
+  void OnCheckArcAvailability(const ArcCallback& callback,
+                              dbus::Response* response) {
+    bool available = false;
+    if (!response) {
+      LOG(ERROR) << "Failed to call "
+                 << login_manager::kSessionManagerCheckArcAvailability;
+    } else {
+      dbus::MessageReader reader(response);
+      if (!reader.PopBool(&available))
+        LOG(ERROR) << "Invalid response: " << response->ToString();
+    }
+    if (!callback.is_null())
+      callback.Run(available);
+  }
+
+  // Called when kSessionManagerStartArcInstance or
+  // kSessionManagerStopArcInstance methods complete.
+  void OnArcMethod(const std::string& method_name,
+                   const ArcCallback& callback,
+                   dbus::Response* response) {
+    bool success = false;
+    if (!response) {
+      LOG(ERROR) << "Failed to call " << method_name;
+    } else {
+      success = true;
+    }
+
+    if (!callback.is_null())
+      callback.Run(success);
+  }
 
   dbus::ObjectProxy* session_manager_proxy_;
   scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
@@ -797,6 +863,19 @@
       callback.Run(state_keys);
   }
 
+  void CheckArcAvailability(const ArcCallback& callback) override {
+    callback.Run(false);
+  }
+
+  void StartArcInstance(const std::string& socket_path,
+                        const ArcCallback& callback) override {
+    callback.Run(false);
+  }
+
+  void StopArcInstance(const ArcCallback& callback) override {
+    callback.Run(false);
+  }
+
  private:
   StubDelegate* delegate_;  // Weak pointer; may be NULL.
   base::ObserverList<Observer> observers_;
diff --git a/chromeos/dbus/session_manager_client.h b/chromeos/dbus/session_manager_client.h
index ba21997..c80688d 100644
--- a/chromeos/dbus/session_manager_client.h
+++ b/chromeos/dbus/session_manager_client.h
@@ -191,6 +191,24 @@
   // will be invoked with an empty state key vector in case of errors.
   virtual void GetServerBackedStateKeys(const StateKeysCallback& callback) = 0;
 
+  // Used for CheckArcAvailability.  Takes a boolean indicating whether the
+  // operation was successful or not.
+  typedef base::Callback<void(bool)> ArcCallback;
+
+  // Asynchronously checks if starting the ARC instance is available.
+  // The result of the operation is reported through |callback|.
+  virtual void CheckArcAvailability(const ArcCallback& callback) = 0;
+
+  // Asynchronously starts the ARC instance using |socket_path| as the IPC
+  // socket for communication with the instance.  Upon completion, invokes
+  // |callback| with the result.
+  virtual void StartArcInstance(const std::string& socket_path,
+                                const ArcCallback& callback) = 0;
+
+  // Asynchronously stops the ARC instance.  Upon completion, invokes
+  // |callback| with the result.
+  virtual void StopArcInstance(const ArcCallback& callback) = 0;
+
   // Creates the instance.
   static SessionManagerClient* Create(DBusClientImplementationType type);
 
diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc
index f86902a..a71a1ce 100644
--- a/chromeos/network/network_state.cc
+++ b/chromeos/network/network_state.cc
@@ -126,6 +126,8 @@
     return GetStringValue(key, value, &security_class_);
   } else if (key == shill::kEapMethodProperty) {
     return GetStringValue(key, value, &eap_method_);
+  } else if (key == shill::kEapKeyMgmtProperty) {
+    return GetStringValue(key, value, &eap_key_mgmt_);
   } else if (key == shill::kNetworkTechnologyProperty) {
     return GetStringValue(key, value, &network_technology_);
   } else if (key == shill::kDeviceProperty) {
@@ -336,6 +338,11 @@
   return connection_state_;
 }
 
+bool NetworkState::IsDynamicWep() const {
+  return security_class_ == shill::kSecurityWep &&
+         eap_key_mgmt_ == shill::kKeyManagementIEEE8021X;
+}
+
 bool NetworkState::IsConnectedState() const {
   return visible() && StateIsConnected(connection_state_);
 }
diff --git a/chromeos/network/network_state.h b/chromeos/network/network_state.h
index b271ca2..d388a8e 100644
--- a/chromeos/network/network_state.h
+++ b/chromeos/network/network_state.h
@@ -99,6 +99,9 @@
     return third_party_vpn_provider_extension_id_;
   }
 
+  // Returns true if the network securty is WEP_8021x (Dynamic WEP)
+  bool IsDynamicWep() const;
+
   // Returns true if |connection_state_| is a connected/connecting state.
   bool IsConnectedState() const;
   bool IsConnectingState() const;
@@ -153,6 +156,7 @@
   // request properties from Shill.
   std::string security_class_;
   std::string eap_method_;  // Needed for WiFi EAP networks
+  std::string eap_key_mgmt_;  // Needed for identifying Dynamic WEP networks
   std::string device_path_;
   std::string guid_;
   std::string connection_state_;
diff --git a/chromeos/network/onc/onc_translator_onc_to_shill.cc b/chromeos/network/onc/onc_translator_onc_to_shill.cc
index 0e84300..81d0733a 100644
--- a/chromeos/network/onc/onc_translator_onc_to_shill.cc
+++ b/chromeos/network/onc/onc_translator_onc_to_shill.cc
@@ -29,9 +29,6 @@
 
 namespace {
 
-// TODO(pstew): Remove once crosreview.com/310644 lands and merges to Chrome.
-const char kKeyManagementIEEE8021X[] = "IEEE8021X";
-
 scoped_ptr<base::StringValue> ConvertValueToString(const base::Value& value) {
   std::string str;
   if (!value.GetAsString(&str))
@@ -225,7 +222,7 @@
                              shill::kSecurityClassProperty);
     if (security == ::onc::wifi::kWEP_8021X) {
       shill_dictionary_->SetStringWithoutPathExpansion(
-          shill::kEapKeyMgmtProperty, kKeyManagementIEEE8021X);
+          shill::kEapKeyMgmtProperty, shill::kKeyManagementIEEE8021X);
     }
   }
 
diff --git a/chromeos/network/onc/onc_translator_shill_to_onc.cc b/chromeos/network/onc/onc_translator_shill_to_onc.cc
index e76f5e6..2861737 100644
--- a/chromeos/network/onc/onc_translator_shill_to_onc.cc
+++ b/chromeos/network/onc/onc_translator_shill_to_onc.cc
@@ -27,9 +27,6 @@
 
 namespace {
 
-// TODO(pstew): Remove once crosreview.com/310644 lands and merges to Chrome.
-const char kKeyManagementIEEE8021X[] = "IEEE8021X";
-
 // Converts |str| to a base::Value of the given |type|. If the conversion fails,
 // returns NULL.
 scoped_ptr<base::Value> ConvertStringToValue(const std::string& str,
@@ -339,7 +336,7 @@
       shill_security == shill::kSecurityWep &&
       shill_dictionary_->GetStringWithoutPathExpansion(
           shill::kEapKeyMgmtProperty, &shill_key_mgmt) &&
-      shill_key_mgmt == kKeyManagementIEEE8021X) {
+      shill_key_mgmt == shill::kKeyManagementIEEE8021X) {
     onc_object_->SetStringWithoutPathExpansion(::onc::wifi::kSecurity,
                                                ::onc::wifi::kWEP_8021X);
   } else {
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 6eb0dfb..77025fc 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -126,7 +126,7 @@
       "//components/security_interstitials/core",
       "//components/signin/core/browser",
       "//components/ssl_config",
-      "//components/startup_metric_utils/browser",
+      "//components/startup_metric_utils",
       "//components/sync_driver",
       "//components/sync_sessions",
       "//components/tracing",
diff --git a/components/app_modal/javascript_dialog_manager.cc b/components/app_modal/javascript_dialog_manager.cc
index 4bbddf91..e9f6873 100644
--- a/components/app_modal/javascript_dialog_manager.cc
+++ b/components/app_modal/javascript_dialog_manager.cc
@@ -14,6 +14,7 @@
 #include "components/app_modal/javascript_native_dialog_factory.h"
 #include "components/app_modal/native_app_modal_dialog.h"
 #include "components/url_formatter/elide_url.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/common/javascript_message_type.h"
 #include "grit/components_strings.h"
 #include "net/base/net_util.h"
@@ -198,15 +199,24 @@
   if (extensions_client_->GetExtensionName(web_contents, origin_url, &name))
     return base::UTF8ToUTF16(name);
 
-  // Otherwise, return the formatted URL.
-  base::string16 url_string =
-      url_formatter::FormatUrlForSecurityDisplayOmitScheme(origin_url,
-                                                           accept_lang);
-
-  return l10n_util::GetStringFUTF16(
-      is_alert ? IDS_JAVASCRIPT_ALERT_TITLE
-      : IDS_JAVASCRIPT_MESSAGEBOX_TITLE,
-      base::i18n::GetDisplayStringInLTRDirectionality(url_string));
+  // Otherwise, return the formatted URL. For non-standard URLs such as |data:|,
+  // just say "This page".
+  bool is_same_origin_as_main_frame =
+      (web_contents->GetURL().GetOrigin() == origin_url.GetOrigin());
+  if (origin_url.IsStandard() && !origin_url.SchemeIsFile() &&
+      !origin_url.SchemeIsFileSystem()) {
+    base::string16 url_string =
+        url_formatter::FormatUrlForSecurityDisplayOmitScheme(origin_url,
+                                                             accept_lang);
+    return l10n_util::GetStringFUTF16(
+        is_same_origin_as_main_frame ? IDS_JAVASCRIPT_MESSAGEBOX_TITLE
+                                     : IDS_JAVASCRIPT_MESSAGEBOX_TITLE_IFRAME,
+        base::i18n::GetDisplayStringInLTRDirectionality(url_string));
+  }
+  return l10n_util::GetStringUTF16(
+      is_same_origin_as_main_frame
+          ? IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL
+          : IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL_IFRAME);
 }
 
 void JavaScriptDialogManager::CancelActiveAndPendingDialogs(
diff --git a/components/app_modal_strings.grdp b/components/app_modal_strings.grdp
index f1e413c..09cd5ff6 100644
--- a/components/app_modal_strings.grdp
+++ b/components/app_modal_strings.grdp
@@ -2,17 +2,17 @@
 <grit-part>
 
   <!-- JavaScript Dialog Box strings -->
-  <message name="IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE" desc="Title for JavaScript alert originating from a webpage if there is no hostname to display">
-     JavaScript Alert
-   </message>
-  <message name="IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE" desc="Title for JavaScript prompt and confirm originating from a webpage if there is no hostname to display">
-    JavaScript
-  </message>
-  <message name="IDS_JAVASCRIPT_ALERT_TITLE" desc="Title for JavaScript alert originating from a webpage">
-    The page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says:
-  </message>
   <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE" desc="Title for JavaScript prompt and confirm originating from a webpage">
-    The page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says:
+    <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says:
+  </message>
+  <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_IFRAME" desc="Title for JavaScript prompt and confirm originating from an iframe inside the webpage">
+    An embedded page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says:
+  </message>
+  <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL" desc="Title for JavaScript prompt and confirm originating from a webpage with a non-standard URL such as |data:|">
+    This page says:
+  </message>
+  <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL_IFRAME" desc="Title for JavaScript prompt and confirm originating from an iframe inside the webpage with a non-standard URL such as |data:|">
+    An embedded page on this webpage says:
   </message>
   <message name="IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION" desc="Optional UI shown on the message box, in the form of a checkbox, allowing the user to suppress additional message boxes from the page.">
     Prevent this page from creating additional dialogs.
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index 807a0d1..e6b456d 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -30,7 +30,6 @@
 #include "third_party/WebKit/public/web/WebLabelElement.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebOptionElement.h"
 #include "third_party/WebKit/public/web/WebSelectElement.h"
 #include "third_party/WebKit/public/web/WebTextAreaElement.h"
@@ -44,7 +43,6 @@
 using blink::WebInputElement;
 using blink::WebLabelElement;
 using blink::WebNode;
-using blink::WebNodeList;
 using blink::WebOptionElement;
 using blink::WebSelectElement;
 using blink::WebTextAreaElement;
@@ -1418,11 +1416,26 @@
   std::string lang;
   if (!html_element.isNull())
     lang = html_element.getAttribute("lang").utf8();
-  if ((lang.empty() ||
-       base::StartsWith(lang, "en", base::CompareCase::INSENSITIVE_ASCII)) &&
-      !MatchesPattern(document.title(),
-          base::UTF8ToUTF16("payment|checkout|address|delivery|shipping"))) {
-    return false;
+  if (lang.empty() ||
+      base::StartsWith(lang, "en", base::CompareCase::INSENSITIVE_ASCII)) {
+    std::string title(base::UTF16ToUTF8(base::string16(document.title())));
+    const char* const kKeywords[] = {
+      "payment",
+      "checkout",
+      "address",
+      "delivery",
+      "shipping",
+    };
+
+    bool found = false;
+    for (const auto& keyword : kKeywords) {
+      if (title.find(keyword) != base::string16::npos) {
+        found = true;
+        break;
+      }
+    }
+    if (!found)
+      return false;
   }
 
   return UnownedFormElementsAndFieldSetsToFormData(
diff --git a/components/autofill/content/renderer/form_cache.cc b/components/autofill/content/renderer/form_cache.cc
index 81ddf83..2650b439 100644
--- a/components/autofill/content/renderer/form_cache.cc
+++ b/components/autofill/content/renderer/form_cache.cc
@@ -19,7 +19,6 @@
 #include "third_party/WebKit/public/web/WebFormElement.h"
 #include "third_party/WebKit/public/web/WebInputElement.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebSelectElement.h"
 #include "third_party/WebKit/public/web/WebTextAreaElement.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index f1c7869..69b27bc1 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -34,7 +34,6 @@
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
 #include "third_party/WebKit/public/web/WebView.h"
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 94049ff0..edc99de 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -877,9 +877,9 @@
     const TimeTicks& load_time,
     const TimeTicks& interaction_time,
     const TimeTicks& submission_time) {
-  submitted_form->LogQualityMetrics(load_time, interaction_time,
-                                    submission_time,
-                                    client_->GetRapporService());
+  submitted_form->LogQualityMetrics(
+      load_time, interaction_time, submission_time, client_->GetRapporService(),
+      did_show_suggestions_);
 
   if (submitted_form->ShouldBeCrowdsourced())
     UploadFormData(*submitted_form);
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc
index 7e2175b..cacfe91 100644
--- a/components/autofill/core/browser/autofill_metrics.cc
+++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -649,6 +649,13 @@
                             AUTOFILL_PROFILE_ACTION_ENUM_SIZE);
 }
 
+// static
+void AutofillMetrics::LogAutofillFormSubmittedState(
+    AutofillFormSubmittedState state) {
+  UMA_HISTOGRAM_ENUMERATION("Autofill.FormSubmittedState", state,
+                            AUTOFILL_FORM_SUBMITTED_STATE_ENUM_SIZE);
+}
+
 AutofillMetrics::FormEventLogger::FormEventLogger(bool is_for_credit_card)
     : is_for_credit_card_(is_for_credit_card),
       is_server_data_available_(false),
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h
index cbdbcab..1219c97 100644
--- a/components/autofill/core/browser/autofill_metrics.h
+++ b/components/autofill/core/browser/autofill_metrics.h
@@ -29,6 +29,15 @@
     AUTOFILL_PROFILE_ACTION_ENUM_SIZE,
   };
 
+  enum AutofillFormSubmittedState {
+    NON_FILLABLE_FORM_OR_NEW_DATA,
+    FILLABLE_FORM_AUTOFILLED_ALL,
+    FILLABLE_FORM_AUTOFILLED_SOME,
+    FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS,
+    FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS,
+    AUTOFILL_FORM_SUBMITTED_STATE_ENUM_SIZE,
+  };
+
   enum DeveloperEngagementMetric {
     // Parsed a form that is potentially autofillable.
     FILLABLE_FORM_PARSED = 0,
@@ -590,6 +599,10 @@
   // action happened.
   static void LogProfileActionOnFormSubmitted(AutofillProfileAction action);
 
+  // This should be called at each form submission to indicate the autofilled
+  // state of the form.
+  static void LogAutofillFormSubmittedState(AutofillFormSubmittedState state);
+
   // Utility to autofill form events in the relevant histograms depending on
   // the presence of server and/or local data.
   class FormEventLogger {
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc
index 9e19220..f91dcc2 100644
--- a/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -2682,9 +2682,8 @@
                                      1);
 }
 
-// Verify that we correctly log user happiness metrics dealing with form loading
-// and form submission.
-TEST_F(AutofillMetricsTest, UserHappinessFormLoadAndSubmission) {
+// Verify that we correctly log the submitted form's state.
+TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
   // Start with a form with insufficiently many fields.
   FormData form;
   form.name = ASCIIToUTF16("TestForm");
@@ -2696,87 +2695,76 @@
   form.fields.push_back(field);
   test::CreateTestFormField("Email", "email", "", "text", &field);
   form.fields.push_back(field);
-
+  test::CreateTestFormField("Phone", "phone", "", "text", &field);
+  form.fields.push_back(field);
+  test::CreateTestFormField("Unknown", "unknown", "", "text", &field);
+  form.fields.push_back(field);
   std::vector<FormData> forms(1, form);
 
   // Expect no notifications when the form is first seen.
   {
     base::HistogramTester histogram_tester;
     autofill_manager_->OnFormsSeen(forms, TimeTicks());
-    histogram_tester.ExpectTotalCount("Autofill.UserHappiness", 0);
+    histogram_tester.ExpectTotalCount("Autofill.FormSubmittedState", 0);
   }
 
-
-  // Expect no notifications when the form is submitted.
-  {
-    base::HistogramTester histogram_tester;
-    autofill_manager_->SubmitForm(form, TimeTicks::Now());
-    histogram_tester.ExpectTotalCount("Autofill.UserHappiness", 0);
-  }
-
-  // Add more fields to the form.
-  test::CreateTestFormField("Phone", "phone", "", "text", &field);
-  form.fields.push_back(field);
-  test::CreateTestFormField("Unknown", "unknown", "", "text", &field);
-  form.fields.push_back(field);
-  forms.front() = form;
-
-  // Expect a notification when the form is first seen.
-  {
-    base::HistogramTester histogram_tester;
-    autofill_manager_->OnFormsSeen(forms, TimeTicks());
-    histogram_tester.ExpectUniqueSample("Autofill.UserHappiness",
-                                        AutofillMetrics::FORMS_LOADED, 1);
-  }
-
-  // Expect a notification when the form is submitted.
+  // No data entered in the form.
   {
     base::HistogramTester histogram_tester;
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
     histogram_tester.ExpectUniqueSample(
-        "Autofill.UserHappiness", AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM,
-        1);
+        "Autofill.FormSubmittedState",
+        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1);
   }
 
-  // Fill in two of the fields.
+  // Non fillable form.
   form.fields[0].value = ASCIIToUTF16("Elvis Aaron Presley");
   form.fields[1].value = ASCIIToUTF16("theking@gmail.com");
   forms.front() = form;
 
-  // Expect a notification when the form is submitted.
   {
     base::HistogramTester histogram_tester;
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
     histogram_tester.ExpectUniqueSample(
-        "Autofill.UserHappiness", AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM,
-        1);
+        "Autofill.FormSubmittedState",
+        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1);
   }
 
   // Fill in the third field.
   form.fields[2].value = ASCIIToUTF16("12345678901");
   forms.front() = form;
 
-  // Expect notifications when the form is submitted.
+  // Autofilled none with no suggestions shown.
   {
     base::HistogramTester histogram_tester;
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
     histogram_tester.ExpectUniqueSample(
-        "Autofill.UserHappiness",
-        AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE, 1);
+        "Autofill.FormSubmittedState",
+        AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS,
+        1);
   }
 
+  // Autofilled none with suggestions shown.
+  autofill_manager_->DidShowSuggestions(true, form, form.fields[2]);
+  {
+    base::HistogramTester histogram_tester;
+    autofill_manager_->SubmitForm(form, TimeTicks::Now());
+    histogram_tester.ExpectUniqueSample(
+        "Autofill.FormSubmittedState",
+        AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS, 1);
+  }
 
   // Mark one of the fields as autofilled.
   form.fields[1].is_autofilled = true;
   forms.front() = form;
 
-  // Expect notifications when the form is submitted.
+  // Autofilled some of the fields.
   {
     base::HistogramTester histogram_tester;
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
     histogram_tester.ExpectUniqueSample(
-        "Autofill.UserHappiness",
-        AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME, 1);
+        "Autofill.FormSubmittedState",
+        AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME, 1);
   }
 
   // Mark all of the fillable fields as autofilled.
@@ -2784,26 +2772,26 @@
   form.fields[2].is_autofilled = true;
   forms.front() = form;
 
-  // Expect notifications when the form is submitted.
+  // Autofilled all the fields.
   {
     base::HistogramTester histogram_tester;
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
     histogram_tester.ExpectUniqueSample(
-        "Autofill.UserHappiness",
-        AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL, 1);
+        "Autofill.FormSubmittedState",
+        AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL, 1);
   }
 
   // Clear out the third field's value.
   form.fields[2].value = base::string16();
   forms.front() = form;
 
-  // Expect notifications when the form is submitted.
+  // Non fillable form.
   {
     base::HistogramTester histogram_tester;
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
     histogram_tester.ExpectUniqueSample(
-        "Autofill.UserHappiness", AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM,
-        1);
+        "Autofill.FormSubmittedState",
+        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1);
   }
 }
 
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 8703ff97..590abf4 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -807,11 +807,11 @@
   form_signature_field_names_ = cached_form.form_signature_field_names_;
 }
 
-void FormStructure::LogQualityMetrics(
-    const base::TimeTicks& load_time,
-    const base::TimeTicks& interaction_time,
-    const base::TimeTicks& submission_time,
-    rappor::RapporService* rappor_service) const {
+void FormStructure::LogQualityMetrics(const base::TimeTicks& load_time,
+                                      const base::TimeTicks& interaction_time,
+                                      const base::TimeTicks& submission_time,
+                                      rappor::RapporService* rappor_service,
+                                      bool did_show_suggestions) const {
   size_t num_detected_field_types = 0;
   size_t num_server_mismatches = 0;
   size_t num_heuristic_mismatches = 0;
@@ -912,18 +912,22 @@
       num_edited_autofilled_fields);
 
   if (num_detected_field_types < kRequiredAutofillFields) {
-    AutofillMetrics::LogUserHappinessMetric(
-        AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM);
+    AutofillMetrics::LogAutofillFormSubmittedState(
+        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
   } else {
     if (did_autofill_all_possible_fields) {
-      AutofillMetrics::LogUserHappinessMetric(
-          AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL);
+      AutofillMetrics::LogAutofillFormSubmittedState(
+          AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL);
     } else if (did_autofill_some_possible_fields) {
-      AutofillMetrics::LogUserHappinessMetric(
-          AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME);
+      AutofillMetrics::LogAutofillFormSubmittedState(
+          AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME);
+    } else if (!did_show_suggestions) {
+      AutofillMetrics::LogAutofillFormSubmittedState(
+          AutofillMetrics::
+              FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS);
     } else {
-      AutofillMetrics::LogUserHappinessMetric(
-          AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE);
+      AutofillMetrics::LogAutofillFormSubmittedState(
+          AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS);
     }
 
     // Log some RAPPOR metrics for problematic cases.
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 1777e50..706f651 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -127,7 +127,8 @@
   void LogQualityMetrics(const base::TimeTicks& load_time,
                          const base::TimeTicks& interaction_time,
                          const base::TimeTicks& submission_time,
-                         rappor::RapporService* rappor_service) const;
+                         rappor::RapporService* rappor_service,
+                         bool did_show_suggestions) const;
 
   // Classifies each field in |fields_| based upon its |autocomplete| attribute,
   // if the attribute is available.  The association is stored into the field's
diff --git a/components/bookmarks.gypi b/components/bookmarks.gypi
index 69d5b589..4894b69 100644
--- a/components/bookmarks.gypi
+++ b/components/bookmarks.gypi
@@ -26,6 +26,7 @@
         'keyed_service_core',
         'pref_registry',
         'query_parser',
+        'startup_metric_utils',
         'url_formatter/url_formatter.gyp:url_formatter',
       ],
       'sources': [
diff --git a/components/bookmarks/DEPS b/components/bookmarks/DEPS
index 1871065..75997b1 100644
--- a/components/bookmarks/DEPS
+++ b/components/bookmarks/DEPS
@@ -3,6 +3,7 @@
   "+components/keyed_service",
   "+components/pref_registry",
   "+components/query_parser",
+  "+components/startup_metric_utils",
   "+components/url_formatter",
   "+grit/components_strings.h",
   "+jni",
diff --git a/components/bookmarks/browser/BUILD.gn b/components/bookmarks/browser/BUILD.gn
index c0ec3b2..97f5065 100644
--- a/components/bookmarks/browser/BUILD.gn
+++ b/components/bookmarks/browser/BUILD.gn
@@ -50,6 +50,7 @@
     "//components/keyed_service/core",
     "//components/pref_registry",
     "//components/query_parser",
+    "//components/startup_metric_utils",
     "//components/strings",
     "//components/url_formatter",
     "//net",
diff --git a/components/browser_sync_strings.grdp b/components/browser_sync_strings.grdp
new file mode 100644
index 0000000..9a8d9626
--- /dev/null
+++ b/components/browser_sync_strings.grdp
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+
+  <!-- Sync time strings -->
+  <message name="IDS_SYNC_TIME_NEVER" desc="Indicates that the first sync has never completed.">
+    Never
+  </message>
+  <message name="IDS_SYNC_TIME_JUST_NOW" desc="Indicates that a sync cycle just finished.">
+    Just now
+  </message>
+
+</grit-part>
diff --git a/components/components_strings.grd b/components/components_strings.grd
index a91c21db8..b3240a1 100644
--- a/components/components_strings.grd
+++ b/components/components_strings.grd
@@ -135,6 +135,7 @@
       <part file="app_modal_strings.grdp" />
       <part file="autofill_strings.grdp" />
       <part file="bookmark_bar_strings.grdp" />
+      <part file="browser_sync_strings.grdp" />
       <part file="crash_strings.grdp" />
       <part file="data_reduction_proxy_strings.grdp" />
       <part file="dom_distiller_strings.grdp" />
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index fcedb75c..11ab790 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -578,7 +578,7 @@
     ],
     'safe_browsing_db_unittest_sources': [
       'safe_browsing_db/prefix_set_unittest.cc',
-      'safe_browsing_db/safe_browsing_db_util_unittest.cc',
+      'safe_browsing_db/util_unittest.cc',
     ],
     'safe_json_unittest_sources': [
       'safe_json/json_sanitizer_unittest.cc',
diff --git a/components/crash/content/tools/crash_service.cc b/components/crash/content/tools/crash_service.cc
index ed55bbfc..cdb6a50 100644
--- a/components/crash/content/tools/crash_service.cc
+++ b/components/crash/content/tools/crash_service.cc
@@ -405,9 +405,11 @@
       // termination of the service object.
       base::AutoLock lock(info->self->sending_);
       VLOG(1) << "trying to send report for pid = " << info->pid;
-      google_breakpad::ReportResult send_result
-          = info->self->sender_->SendCrashReport(kCrashReportURL, info->map,
-                                                 info->dump_path, &report_id);
+      std::map<std::wstring, std::wstring> file_map;
+      file_map[L"upload_file_minidump"] = info->dump_path;
+      google_breakpad::ReportResult send_result =
+          info->self->sender_->SendCrashReport(kCrashReportURL, info->map,
+                                               file_map, &report_id);
       switch (send_result) {
         case google_breakpad::RESULT_FAILED:
           report_id = L"<network issue>";
diff --git a/components/google/core/browser/google_util.h b/components/google/core/browser/google_util.h
index 0d668314..d26f9cd 100644
--- a/components/google/core/browser/google_util.h
+++ b/components/google/core/browser/google_util.h
@@ -54,9 +54,7 @@
 
 // WARNING: The following IsGoogleXXX() functions use heuristics to rule out
 // "obviously false" answers.  They do NOT guarantee that the string in question
-// is actually on a Google-owned domain, just that it looks plausible.  If you
-// need to restrict some behavior to only happen on Google's officially-owned
-// domains, use TransportSecurityState::IsGooglePinnedProperty() instead.
+// is actually on a Google-owned domain, just that it looks plausible.
 
 // Designate whether or not a URL checking function also checks for specific
 // subdomains, or only "www" and empty subdomains.
diff --git a/components/guest_view/browser/guest_view_manager.cc b/components/guest_view/browser/guest_view_manager.cc
index 8fdc082a..4c86e9d1 100644
--- a/components/guest_view/browser/guest_view_manager.cc
+++ b/components/guest_view/browser/guest_view_manager.cc
@@ -240,8 +240,7 @@
   CHECK(CanUseGuestInstanceID(guest_instance_id));
   guest_web_contents_by_instance_id_[guest_instance_id] = guest_web_contents;
 
-  // Make |guest_web_contents| show up in the task manager.
-  delegate_->AttachTaskManagerGuestTag(guest_web_contents);
+  delegate_->OnGuestAdded(guest_web_contents);
 }
 
 void GuestViewManager::RemoveGuest(int guest_instance_id) {
diff --git a/components/guest_view/browser/guest_view_manager_delegate.h b/components/guest_view/browser/guest_view_manager_delegate.h
index 9a566336..4323c57 100644
--- a/components/guest_view/browser/guest_view_manager_delegate.h
+++ b/components/guest_view/browser/guest_view_manager_delegate.h
@@ -33,11 +33,8 @@
   GuestViewManagerDelegate();
   virtual ~GuestViewManagerDelegate();
 
-  // Attaches the task-manager-specific tag for the GuestViews to its
-  // |guest_web_contents| so that their corresponding tasks show up in the task
-  // manager.
-  virtual void AttachTaskManagerGuestTag(
-      content::WebContents* guest_web_contents) const {}
+  // Invoked after |guest_web_contents| is added.
+  virtual void OnGuestAdded(content::WebContents* guest_web_contents) const {}
 
   // Dispatches the event with |name| with the provided |args| to the embedder
   // of the given |guest| with |instance_id| for routing.
diff --git a/components/history/core/browser/typed_url_model_associator.cc b/components/history/core/browser/typed_url_model_associator.cc
index 38be8e8..31a3979 100644
--- a/components/history/core/browser/typed_url_model_associator.cc
+++ b/components/history/core/browser/typed_url_model_associator.cc
@@ -211,19 +211,23 @@
 
     // Get all the visits.
     std::map<history::URLID, history::VisitVector> visit_vectors;
+    history::URLRows::iterator new_end = typed_urls.end();
     for (history::URLRows::iterator ix = typed_urls.begin();
-         ix != typed_urls.end();) {
+         ix != new_end;) {
       DCHECK_EQ(0U, visit_vectors.count(ix->id()));
       if (!FixupURLAndGetVisits(&(*ix), &(visit_vectors[ix->id()])) ||
           ShouldIgnoreUrl(ix->url()) ||
           ShouldIgnoreVisits(visit_vectors[ix->id()])) {
         // Ignore this URL if we couldn't load the visits or if there's some
         // other problem with it (it was empty, or imported and never visited).
-        ix = typed_urls.erase(ix);
+        --new_end;
+        if (ix != new_end)
+          *ix = *new_end;
       } else {
         ++ix;
       }
     }
+    typed_urls.erase(new_end, typed_urls.end());
 
     syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
     syncer::ReadNode typed_url_root(&trans);
diff --git a/components/history/core/browser/url_row.cc b/components/history/core/browser/url_row.cc
index 1f484c8..71c3725 100644
--- a/components/history/core/browser/url_row.cc
+++ b/components/history/core/browser/url_row.cc
@@ -28,6 +28,8 @@
 }
 
 URLRow& URLRow::operator=(const URLRow& other) {
+  if (this == &other)
+    return *this;
   id_ = other.id_;
   url_ = other.url_;
   title_ = other.title_;
diff --git a/components/html_viewer/BUILD.gn b/components/html_viewer/BUILD.gn
index d88dd51d..b1ed623 100644
--- a/components/html_viewer/BUILD.gn
+++ b/components/html_viewer/BUILD.gn
@@ -161,7 +161,7 @@
     "//components/resource_provider/public/cpp",
     "//components/resource_provider/public/interfaces",
     "//components/scheduler:scheduler",
-    "//components/startup_metric_utils/browser",
+    "//components/startup_metric_utils",
     "//components/webcrypto",
     "//components/web_view:switches",
     "//components/web_view/public/interfaces",
diff --git a/components/html_viewer/DEPS b/components/html_viewer/DEPS
index 3ba0df9..e87124c6 100644
--- a/components/html_viewer/DEPS
+++ b/components/html_viewer/DEPS
@@ -10,7 +10,7 @@
   "+components/mus",
   "+components/resource_provider/public",
   "+components/scheduler",
-  "+components/startup_metric_utils/browser",
+  "+components/startup_metric_utils",
   "+components/webcrypto",
   "+components/web_view/public/interfaces",
   "+components/web_view/test_runner/public/interfaces",
diff --git a/components/html_viewer/blink_platform_impl.cc b/components/html_viewer/blink_platform_impl.cc
index 1f578ab..b8eb54f 100644
--- a/components/html_viewer/blink_platform_impl.cc
+++ b/components/html_viewer/blink_platform_impl.cc
@@ -124,11 +124,11 @@
   return &blob_registry_;
 }
 
-double BlinkPlatformImpl::currentTime() {
+double BlinkPlatformImpl::currentTimeSeconds() {
   return base::Time::Now().ToDoubleT();
 }
 
-double BlinkPlatformImpl::monotonicallyIncreasingTime() {
+double BlinkPlatformImpl::monotonicallyIncreasingTimeSeconds() {
   return base::TimeTicks::Now().ToInternalValue() /
       static_cast<double>(base::Time::kMicrosecondsPerSecond);
 }
diff --git a/components/html_viewer/blink_platform_impl.h b/components/html_viewer/blink_platform_impl.h
index aa180bcd..267674a 100644
--- a/components/html_viewer/blink_platform_impl.h
+++ b/components/html_viewer/blink_platform_impl.h
@@ -49,8 +49,8 @@
   virtual blink::WebThemeEngine* themeEngine();
   virtual blink::WebString defaultLocale();
   virtual blink::WebBlobRegistry* blobRegistry();
-  virtual double currentTime();
-  virtual double monotonicallyIncreasingTime();
+  virtual double currentTimeSeconds();
+  virtual double monotonicallyIncreasingTimeSeconds();
   virtual void cryptographicallyRandomValues(unsigned char* buffer,
                                              size_t length);
   virtual bool isThreadedCompositingEnabled();
diff --git a/components/html_viewer/stats_collection_controller.cc b/components/html_viewer/stats_collection_controller.cc
index 8abc09a7..70ab672 100644
--- a/components/html_viewer/stats_collection_controller.cc
+++ b/components/html_viewer/stats_collection_controller.cc
@@ -9,7 +9,7 @@
 #include "base/metrics/histogram.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/time/time.h"
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 #include "gin/handle.h"
 #include "gin/object_template_builder.h"
 #include "mojo/application/public/cpp/application_impl.h"
diff --git a/components/mus/ws/BUILD.gn b/components/mus/ws/BUILD.gn
index 4fa7f94..bc2d0af7 100644
--- a/components/mus/ws/BUILD.gn
+++ b/components/mus/ws/BUILD.gn
@@ -41,12 +41,16 @@
     "transient_window_manager.cc",
     "transient_window_manager.h",
     "transient_window_observer.h",
+    "transient_window_stacking_client.cc",
+    "transient_window_stacking_client.h",
     "window_coordinate_conversions.cc",
     "window_coordinate_conversions.h",
     "window_finder.cc",
     "window_finder.h",
     "window_manager_access_policy.cc",
     "window_manager_access_policy.h",
+    "window_stacking_client.cc",
+    "window_stacking_client.h",
     "window_tree_host_connection.cc",
     "window_tree_host_connection.h",
     "window_tree_host_delegate.h",
@@ -54,6 +58,8 @@
     "window_tree_host_impl.h",
     "window_tree_impl.cc",
     "window_tree_impl.h",
+    "window_utils.cc",
+    "window_utils.h",
   ]
 
   deps = [
diff --git a/components/mus/ws/server_window.cc b/components/mus/ws/server_window.cc
index b0348d40..e29c0aa 100644
--- a/components/mus/ws/server_window.cc
+++ b/components/mus/ws/server_window.cc
@@ -10,6 +10,7 @@
 #include "components/mus/ws/server_window_delegate.h"
 #include "components/mus/ws/server_window_observer.h"
 #include "components/mus/ws/server_window_surface_manager.h"
+#include "components/mus/ws/window_stacking_client.h"
 #include "mojo/converters/geometry/geometry_type_converters.h"
 
 namespace mus {
@@ -103,6 +104,12 @@
   DCHECK(child);
   DCHECK(child->parent() == this);
   DCHECK_GT(children_.size(), 1u);
+
+  WindowStackingClient* stacking_client = GetWindowStackingClient();
+  if (stacking_client &&
+      !stacking_client->AdjustStacking(&child, &relative, &direction))
+    return;
+
   children_.erase(std::find(children_.begin(), children_.end(), child));
   Windows::iterator i = std::find(children_.begin(), children_.end(), relative);
   if (direction == mojom::ORDER_DIRECTION_ABOVE) {
@@ -114,6 +121,21 @@
   }
   FOR_EACH_OBSERVER(ServerWindowObserver, observers_,
                     OnWindowReordered(this, relative, direction));
+  child->OnStackingChanged();
+}
+
+void ServerWindow::StackChildAtBottom(ServerWindow* child) {
+  // There's nothing to do if the child is already at the bottom.
+  if (children_.size() <= 1 || child == children_.front())
+    return;
+  Reorder(child, children_.front(), mojom::ORDER_DIRECTION_BELOW);
+}
+
+void ServerWindow::StackChildAtTop(ServerWindow* child) {
+  // There's nothing to do if the child is already at the top.
+  if (children_.size() <= 1 || child == children_.back())
+    return;
+  Reorder(child, children_.back(), mojom::ORDER_DIRECTION_ABOVE);
 }
 
 void ServerWindow::SetBounds(const gfx::Rect& bounds) {
@@ -275,6 +297,11 @@
   children_.erase(std::find(children_.begin(), children_.end(), window));
 }
 
+void ServerWindow::OnStackingChanged() {
+  FOR_EACH_OBSERVER(ServerWindowObserver, observers_,
+                    OnWindowStackingChanged(this));
+}
+
 }  // namespace ws
 
 }  // namespace mus
diff --git a/components/mus/ws/server_window.h b/components/mus/ws/server_window.h
index 614c082..5f34873 100644
--- a/components/mus/ws/server_window.h
+++ b/components/mus/ws/server_window.h
@@ -60,6 +60,8 @@
   void Reorder(ServerWindow* child,
                ServerWindow* relative,
                mojom::OrderDirection direction);
+  void StackChildAtBottom(ServerWindow* child);
+  void StackChildAtTop(ServerWindow* child);
 
   const gfx::Rect& bounds() const { return bounds_; }
   // Sets the bounds. If the size changes this implicitly resets the client
@@ -127,10 +129,12 @@
 #endif
 
  private:
-
   // Implementation of removing a window. Doesn't send any notification.
   void RemoveImpl(ServerWindow* window);
 
+  // Called when this window's stacking order among its siblings is changed.
+  void OnStackingChanged();
+
   ServerWindowDelegate* delegate_;
   const WindowId id_;
   ServerWindow* parent_;
diff --git a/components/mus/ws/server_window_observer.h b/components/mus/ws/server_window_observer.h
index be51d04..952610bc 100644
--- a/components/mus/ws/server_window_observer.h
+++ b/components/mus/ws/server_window_observer.h
@@ -54,6 +54,8 @@
                                  ServerWindow* relative,
                                  mojom::OrderDirection direction) {}
 
+  virtual void OnWindowStackingChanged(ServerWindow* window) {}
+
   virtual void OnWillChangeWindowVisibility(ServerWindow* window) {}
   virtual void OnWindowVisibilityChanged(ServerWindow* window) {}
 
diff --git a/components/mus/ws/transient_window_manager.cc b/components/mus/ws/transient_window_manager.cc
index 29c7d39..81f0977 100644
--- a/components/mus/ws/transient_window_manager.cc
+++ b/components/mus/ws/transient_window_manager.cc
@@ -4,11 +4,14 @@
 
 #include "components/mus/ws/transient_window_manager.h"
 
+#include <vector>
+
 #include "base/auto_reset.h"
 #include "base/lazy_instance.h"
 #include "base/stl_util.h"
 #include "components/mus/ws/server_window.h"
 #include "components/mus/ws/transient_window_observer.h"
+#include "components/mus/ws/window_utils.h"
 
 namespace mus {
 namespace ws {
@@ -37,6 +40,12 @@
 
 // static
 TransientWindowManager* TransientWindowManager::Get(ServerWindow* window) {
+  return const_cast<TransientWindowManager*>(
+      Get(const_cast<const ServerWindow*>(window)));
+}
+
+const TransientWindowManager* TransientWindowManager::Get(
+    const ServerWindow* window) {
   TransientWindowManagerMap* map = transient_window_manager_map.Pointer();
   auto it = map->find(window);
   return it == map->end() ? nullptr : it->second;
@@ -59,6 +68,11 @@
   transient_children_.push_back(child);
   child_manager->transient_parent_ = window_;
 
+  // Restack |child| properly above its transient parent, if they share the same
+  // parent.
+  if (child->parent() == window_->parent())
+    RestackTransientDescendants();
+
   FOR_EACH_OBSERVER(TransientWindowObserver, observers_,
                     OnTransientChildAdded(window_, child));
 }
@@ -73,16 +87,45 @@
   DCHECK_EQ(window_, child_manager->transient_parent_);
   child_manager->transient_parent_ = nullptr;
 
+  // If |child| and its former transient parent share the same parent, |child|
+  // should be restacked properly so it is not among transient children of its
+  // former parent, anymore.
+  if (window_->parent() == child->parent())
+    RestackTransientDescendants();
+
   FOR_EACH_OBSERVER(TransientWindowObserver, observers_,
                     OnTransientChildRemoved(window_, child));
 }
 
+bool TransientWindowManager::IsStackingTransient(
+    const ServerWindow* target) const {
+  return stacking_target_ == target;
+}
+
 TransientWindowManager::TransientWindowManager(ServerWindow* window)
-    : window_(window),
-      transient_parent_(nullptr) {
+    : window_(window), transient_parent_(nullptr), stacking_target_(nullptr) {
   window_->AddObserver(this);
 }
 
+void TransientWindowManager::RestackTransientDescendants() {
+  ServerWindow* parent = window_->parent();
+  if (!parent)
+    return;
+
+  // stack any transient children that share the same parent to be in front of
+  // |window_|. the existing stacking order is preserved by iterating backwards
+  // and always stacking on top.
+  Windows children(parent->children());
+  for (auto it = children.rbegin(); it != children.rend(); ++it) {
+    if ((*it) != window_ && HasTransientAncestor(*it, window_)) {
+      TransientWindowManager* descendant_manager = GetOrCreate(*it);
+      base::AutoReset<ServerWindow*> resetter(
+          &descendant_manager->stacking_target_, window_);
+      parent->Reorder((*it), window_, mojom::ORDER_DIRECTION_ABOVE);
+    }
+  }
+}
+
 void TransientWindowManager::OnWillDestroyWindow(ServerWindow* window) {
   // Removes ourselves from our transient parent (if it hasn't been done by the
   // RootWindow).
@@ -99,10 +142,39 @@
   DCHECK(transient_children_.empty());
 }
 
+void TransientWindowManager::OnWindowStackingChanged(ServerWindow* window) {
+  // Do nothing if we initiated the stacking change.
+  const TransientWindowManager* transient_manager = Get(window);
+  if (transient_manager && transient_manager->stacking_target_) {
+    Windows::const_iterator window_i =
+        std::find(window->parent()->children().begin(),
+                  window->parent()->children().end(), window);
+    DCHECK(window_i != window->parent()->children().end());
+    if (window_i != window->parent()->children().begin() &&
+        (*(window_i - 1) == transient_manager->stacking_target_))
+      return;
+  }
+
+  RestackTransientDescendants();
+}
+
 void TransientWindowManager::OnWindowDestroyed(ServerWindow* window) {
   transient_window_manager_map.Get().erase(window_);
   delete this;
 }
 
+void TransientWindowManager::OnWindowHierarchyChanged(
+    ServerWindow* window,
+    ServerWindow* new_parent,
+    ServerWindow* old_parent) {
+  DCHECK_EQ(window_, window);
+  // Stack |window| properly if it is transient child of a sibling.
+  ServerWindow* transient_parent = GetTransientParent(window);
+  if (transient_parent && transient_parent->parent() == new_parent) {
+    TransientWindowManager* transient_parent_manager = Get(transient_parent);
+    transient_parent_manager->RestackTransientDescendants();
+  }
+}
+
 }  // namespace ws
 }  // namespace mus
diff --git a/components/mus/ws/transient_window_manager.h b/components/mus/ws/transient_window_manager.h
index 4c78ee9..543ab13 100644
--- a/components/mus/ws/transient_window_manager.h
+++ b/components/mus/ws/transient_window_manager.h
@@ -37,6 +37,7 @@
   // Returns the TransientWindowManager for |window| only if it already exists.
   // WARNING: this may return nullptr.
   static TransientWindowManager* Get(ServerWindow* window);
+  static const TransientWindowManager* Get(const ServerWindow* window);
 
   void AddObserver(TransientWindowObserver* observer);
   void RemoveObserver(TransientWindowObserver* observer);
@@ -49,17 +50,36 @@
   ServerWindow* transient_parent() { return transient_parent_; }
   const ServerWindow* transient_parent() const { return transient_parent_; }
 
+  // Returns true if in the process of stacking |window_| on top of |target|.
+  // That is, when the stacking order of a window changes
+  // (OnWindowStackingChanged()) the transients may get restacked as well. This
+  // function can be used to detect if TransientWindowManager is in the process
+  // of stacking a transient as the result of window stacking changing.
+  bool IsStackingTransient(const ServerWindow* target) const;
+
  private:
   explicit TransientWindowManager(ServerWindow* window);
 
+  // Stacks transient descendants of this window that are its siblings just
+  // above it.
+  void RestackTransientDescendants();
+
   // ServerWindowObserver:
   void OnWillDestroyWindow(ServerWindow* window) override;
+  void OnWindowStackingChanged(ServerWindow* window) override;
   void OnWindowDestroyed(ServerWindow* window) override;
+  void OnWindowHierarchyChanged(ServerWindow* window,
+                                ServerWindow* new_parent,
+                                ServerWindow* old_parent) override;
 
   ServerWindow* window_;
   ServerWindow* transient_parent_;
   Windows transient_children_;
 
+  // If non-null we're actively restacking transient as the result of a
+  // transient ancestor changing.
+  ServerWindow* stacking_target_;
+
   base::ObserverList<TransientWindowObserver> observers_;
 
   DISALLOW_COPY_AND_ASSIGN(TransientWindowManager);
diff --git a/components/mus/ws/transient_window_manager_unittest.cc b/components/mus/ws/transient_window_manager_unittest.cc
index c923a9fc..c33f95df 100644
--- a/components/mus/ws/transient_window_manager_unittest.cc
+++ b/components/mus/ws/transient_window_manager_unittest.cc
@@ -2,14 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/strings/string_number_conversions.h"
 #include "components/mus/ws/server_window.h"
 #include "components/mus/ws/test_server_window_delegate.h"
 #include "components/mus/ws/transient_window_manager.h"
 #include "components/mus/ws/transient_window_observer.h"
+#include "components/mus/ws/transient_window_stacking_client.h"
+#include "components/mus/ws/window_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mus {
-
 namespace ws {
 
 namespace {
@@ -52,8 +54,15 @@
   return window;
 }
 
-void AddTransientChild(ServerWindow* parent, ServerWindow* child) {
-  TransientWindowManager::GetOrCreate(parent)->AddTransientChild(child);
+std::string ChildWindowIDsAsString(ServerWindow* parent) {
+  std::string result;
+  for (auto i = parent->children().begin(); i != parent->children().end();
+       ++i) {
+    if (!result.empty())
+      result += " ";
+    result += base::IntToString(WindowIdToTransportId((*i)->id()));
+  }
+  return result;
 }
 
 }  // namespace
@@ -63,11 +72,19 @@
   TransientWindowManagerTest() {}
   ~TransientWindowManagerTest() override {}
 
+  void SetUp() override {
+    client_.reset(new TransientWindowStackingClient);
+    SetWindowStackingClient(client_.get());
+  }
+
+  void TearDown() override { SetWindowStackingClient(nullptr); }
+
  private:
+  scoped_ptr<TransientWindowStackingClient> client_;
   DISALLOW_COPY_AND_ASSIGN(TransientWindowManagerTest);
 };
 
-TEST(TransientWindowManagerTest, TransientChildren) {
+TEST_F(TransientWindowManagerTest, TransientChildren) {
   TestServerWindowDelegate server_window_delegate;
 
   scoped_ptr<ServerWindow> parent(
@@ -79,8 +96,11 @@
 
   ServerWindow* w2 =
       CreateTestWindow(&server_window_delegate, WindowId(1, 3), parent.get());
+
   // w2 is now owned by w1.
   AddTransientChild(w1.get(), w2);
+  // Stack w1 at the top (end), this should force w2 to be last (on top of w1).
+  parent->StackChildAtTop(w1.get());
   ASSERT_EQ(3u, parent->children().size());
   EXPECT_EQ(w2, parent->children().back());
 
@@ -91,6 +111,243 @@
   EXPECT_EQ(w3.get(), parent->children()[0]);
 }
 
-}  // namespace ws
+// Tests that transient children are stacked as a unit when using stack above.
+TEST_F(TransientWindowManagerTest, TransientChildrenGroupAbove) {
+  TestServerWindowDelegate server_window_delegate;
 
+  scoped_ptr<ServerWindow> parent(
+      CreateTestWindow(&server_window_delegate, WindowId(), nullptr));
+  scoped_ptr<ServerWindow> w1(
+      CreateTestWindow(&server_window_delegate, WindowId(0, 1), parent.get()));
+
+  ServerWindow* w11 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 11), parent.get());
+  scoped_ptr<ServerWindow> w2(
+      CreateTestWindow(&server_window_delegate, WindowId(0, 2), parent.get()));
+
+  ServerWindow* w21 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 21), parent.get());
+  ServerWindow* w211 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 211), parent.get());
+  ServerWindow* w212 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 212), parent.get());
+  ServerWindow* w213 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 213), parent.get());
+  ServerWindow* w22 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 22), parent.get());
+  ASSERT_EQ(8u, parent->children().size());
+
+  // w11 is now owned by w1.
+  AddTransientChild(w1.get(), w11);
+  // w21 is now owned by w2.
+  AddTransientChild(w2.get(), w21);
+  // w22 is now owned by w2.
+  AddTransientChild(w2.get(), w22);
+  // w211 is now owned by w21.
+  AddTransientChild(w21, w211);
+  // w212 is now owned by w21.
+  AddTransientChild(w21, w212);
+  // w213 is now owned by w21.
+  AddTransientChild(w21, w213);
+  EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
+
+  // Stack w1 at the top (end), this should force w11 to be last (on top of w1).
+  parent->StackChildAtTop(w1.get());
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
+
+  // This tests that the order in children_ array rather than in
+  // transient_children_ array is used when reinserting transient children.
+  // If transient_children_ array was used '22' would be following '21'.
+  parent->StackChildAtTop(w2.get());
+  EXPECT_EQ(w22, parent->children().back());
+  EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w11, w2.get(), mojom::ORDER_DIRECTION_ABOVE);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w21, w1.get(), mojom::ORDER_DIRECTION_ABOVE);
+  EXPECT_EQ(w22, parent->children().back());
+  EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w21, w22, mojom::ORDER_DIRECTION_ABOVE);
+  EXPECT_EQ(w213, parent->children().back());
+  EXPECT_EQ("1 11 2 22 21 211 212 213", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w11, w21, mojom::ORDER_DIRECTION_ABOVE);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 22 21 211 212 213 1 11", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w213, w21, mojom::ORDER_DIRECTION_ABOVE);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
+
+  // No change when stacking a transient parent above its transient child.
+  parent->Reorder(w21, w211, mojom::ORDER_DIRECTION_ABOVE);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
+
+  // This tests that the order in children_ array rather than in
+  // transient_children_ array is used when reinserting transient children.
+  // If transient_children_ array was used '22' would be following '21'.
+  parent->Reorder(w2.get(), w1.get(), mojom::ORDER_DIRECTION_ABOVE);
+  EXPECT_EQ(w212, parent->children().back());
+  EXPECT_EQ("1 11 2 22 21 213 211 212", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w11, w213, mojom::ORDER_DIRECTION_ABOVE);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
+}
+
+TEST_F(TransientWindowManagerTest, TransienChildGroupBelow) {
+  TestServerWindowDelegate server_window_delegate;
+
+  scoped_ptr<ServerWindow> parent(
+      CreateTestWindow(&server_window_delegate, WindowId(), nullptr));
+  scoped_ptr<ServerWindow> w1(
+      CreateTestWindow(&server_window_delegate, WindowId(0, 1), parent.get()));
+
+  ServerWindow* w11 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 11), parent.get());
+  scoped_ptr<ServerWindow> w2(
+      CreateTestWindow(&server_window_delegate, WindowId(0, 2), parent.get()));
+
+  ServerWindow* w21 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 21), parent.get());
+  ServerWindow* w211 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 211), parent.get());
+  ServerWindow* w212 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 212), parent.get());
+  ServerWindow* w213 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 213), parent.get());
+  ServerWindow* w22 =
+      CreateTestWindow(&server_window_delegate, WindowId(0, 22), parent.get());
+  ASSERT_EQ(8u, parent->children().size());
+
+  // w11 is now owned by w1.
+  AddTransientChild(w1.get(), w11);
+  // w21 is now owned by w2.
+  AddTransientChild(w2.get(), w21);
+  // w22 is now owned by w2.
+  AddTransientChild(w2.get(), w22);
+  // w211 is now owned by w21.
+  AddTransientChild(w21, w211);
+  // w212 is now owned by w21.
+  AddTransientChild(w21, w212);
+  // w213 is now owned by w21.
+  AddTransientChild(w21, w213);
+  EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
+
+  // Stack w2 at the bottom, this should force w11 to be last (on top of w1).
+  // This also tests that the order in children_ array rather than in
+  // transient_children_ array is used when reinserting transient children.
+  // If transient_children_ array was used '22' would be following '21'.
+  parent->StackChildAtBottom(w2.get());
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
+
+  parent->StackChildAtBottom(w1.get());
+  EXPECT_EQ(w22, parent->children().back());
+  EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w21, w1.get(), mojom::ORDER_DIRECTION_BELOW);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w11, w2.get(), mojom::ORDER_DIRECTION_BELOW);
+  EXPECT_EQ(w22, parent->children().back());
+  EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w22, w21, mojom::ORDER_DIRECTION_BELOW);
+  EXPECT_EQ(w213, parent->children().back());
+  EXPECT_EQ("1 11 2 22 21 211 212 213", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w21, w11, mojom::ORDER_DIRECTION_BELOW);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 22 21 211 212 213 1 11", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w213, w211, mojom::ORDER_DIRECTION_BELOW);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
+
+  // No change when stacking a transient parent below its transient child.
+  parent->Reorder(w21, w211, mojom::ORDER_DIRECTION_BELOW);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w1.get(), w2.get(), mojom::ORDER_DIRECTION_BELOW);
+  EXPECT_EQ(w212, parent->children().back());
+  EXPECT_EQ("1 11 2 22 21 213 211 212", ChildWindowIDsAsString(parent.get()));
+
+  parent->Reorder(w213, w11, mojom::ORDER_DIRECTION_BELOW);
+  EXPECT_EQ(w11, parent->children().back());
+  EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
+}
+
+// Tests that transient windows are stacked properly when created.
+TEST_F(TransientWindowManagerTest, StackUponCreation) {
+  TestServerWindowDelegate delegate;
+  scoped_ptr<ServerWindow> parent(
+      CreateTestWindow(&delegate, WindowId(), nullptr));
+  scoped_ptr<ServerWindow> window0(
+      CreateTestWindow(&delegate, WindowId(0, 1), parent.get()));
+  scoped_ptr<ServerWindow> window1(
+      CreateTestWindow(&delegate, WindowId(0, 2), parent.get()));
+
+  ServerWindow* window2 =
+      CreateTestWindow(&delegate, WindowId(0, 3), parent.get());
+  AddTransientChild(window0.get(), window2);
+  EXPECT_EQ("1 3 2", ChildWindowIDsAsString(parent.get()));
+}
+
+// Tests that windows are restacked properly after a call to AddTransientChild()
+// or RemoveTransientChild().
+TEST_F(TransientWindowManagerTest, RestackUponAddOrRemoveTransientChild) {
+  TestServerWindowDelegate delegate;
+  scoped_ptr<ServerWindow> parent(
+      CreateTestWindow(&delegate, WindowId(), nullptr));
+  scoped_ptr<ServerWindow> windows[4];
+  for (int i = 0; i < 4; i++)
+    windows[i].reset(CreateTestWindow(&delegate, WindowId(0, i), parent.get()));
+
+  EXPECT_EQ("0 1 2 3", ChildWindowIDsAsString(parent.get()));
+
+  AddTransientChild(windows[0].get(), windows[2].get());
+  EXPECT_EQ("0 2 1 3", ChildWindowIDsAsString(parent.get()));
+
+  AddTransientChild(windows[0].get(), windows[3].get());
+  EXPECT_EQ("0 2 3 1", ChildWindowIDsAsString(parent.get()));
+
+  RemoveTransientChild(windows[0].get(), windows[2].get());
+  EXPECT_EQ("0 3 2 1", ChildWindowIDsAsString(parent.get()));
+
+  RemoveTransientChild(windows[0].get(), windows[3].get());
+  EXPECT_EQ("0 3 2 1", ChildWindowIDsAsString(parent.get()));
+}
+
+// Verifies TransientWindowObserver is notified appropriately.
+TEST_F(TransientWindowManagerTest, TransientWindowObserverNotified) {
+  TestServerWindowDelegate delegate;
+  scoped_ptr<ServerWindow> parent(
+      CreateTestWindow(&delegate, WindowId(), nullptr));
+  scoped_ptr<ServerWindow> w1(
+      CreateTestWindow(&delegate, WindowId(0, 1), parent.get()));
+
+  TestTransientWindowObserver test_observer;
+  TransientWindowManager::GetOrCreate(parent.get())
+      ->AddObserver(&test_observer);
+
+  AddTransientChild(parent.get(), w1.get());
+  EXPECT_EQ(1, test_observer.add_count());
+  EXPECT_EQ(0, test_observer.remove_count());
+
+  RemoveTransientChild(parent.get(), w1.get());
+  EXPECT_EQ(1, test_observer.add_count());
+  EXPECT_EQ(1, test_observer.remove_count());
+
+  TransientWindowManager::Get(parent.get())->RemoveObserver(&test_observer);
+}
+
+}  // namespace ws
 }  // namespace mus
diff --git a/components/mus/ws/transient_window_stacking_client.cc b/components/mus/ws/transient_window_stacking_client.cc
new file mode 100644
index 0000000..3ca2bebd
--- /dev/null
+++ b/components/mus/ws/transient_window_stacking_client.cc
@@ -0,0 +1,103 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/mus/ws/transient_window_stacking_client.h"
+
+#include <algorithm>
+
+#include "components/mus/ws/server_window.h"
+#include "components/mus/ws/transient_window_manager.h"
+#include "components/mus/ws/window_utils.h"
+
+namespace mus {
+namespace ws {
+
+namespace {
+
+// Populates |ancestors| with all transient ancestors of |window| that are
+// siblings of |window|. Returns true if any ancestors were found, false if not.
+bool GetAllTransientAncestors(ServerWindow* window,
+                              ServerWindow::Windows* ancestors) {
+  ServerWindow* parent = window->parent();
+  for (; window; window = GetTransientParent(window)) {
+    if (window->parent() == parent)
+      ancestors->push_back(window);
+  }
+  return !ancestors->empty();
+}
+
+// Replaces |window1| and |window2| with their possible transient ancestors that
+// are still siblings (have a common transient parent).  |window1| and |window2|
+// are not modified if such ancestors cannot be found.
+void FindCommonTransientAncestor(ServerWindow** window1,
+                                 ServerWindow** window2) {
+  DCHECK(window1);
+  DCHECK(window2);
+  DCHECK(*window1);
+  DCHECK(*window2);
+  // Assemble chains of ancestors of both windows.
+  ServerWindow::Windows ancestors1;
+  ServerWindow::Windows ancestors2;
+  if (!GetAllTransientAncestors(*window1, &ancestors1) ||
+      !GetAllTransientAncestors(*window2, &ancestors2)) {
+    return;
+  }
+  // Walk the two chains backwards and look for the first difference.
+  ServerWindow::Windows::reverse_iterator it1 = ancestors1.rbegin();
+  ServerWindow::Windows::reverse_iterator it2 = ancestors2.rbegin();
+  for (; it1 != ancestors1.rend() && it2 != ancestors2.rend(); ++it1, ++it2) {
+    if (*it1 != *it2) {
+      *window1 = *it1;
+      *window2 = *it2;
+      break;
+    }
+  }
+}
+
+}  // namespace
+
+// static
+TransientWindowStackingClient* TransientWindowStackingClient::instance_ = NULL;
+
+TransientWindowStackingClient::TransientWindowStackingClient() {
+  instance_ = this;
+}
+
+TransientWindowStackingClient::~TransientWindowStackingClient() {
+  if (instance_ == this)
+    instance_ = NULL;
+}
+
+bool TransientWindowStackingClient::AdjustStacking(
+    ServerWindow** child,
+    ServerWindow** target,
+    mojom::OrderDirection* direction) {
+  const TransientWindowManager* transient_manager =
+      TransientWindowManager::Get(static_cast<const ServerWindow*>(*child));
+  if (transient_manager && transient_manager->IsStackingTransient(*target))
+    return true;
+
+  // For windows that have transient children stack the transient ancestors that
+  // are siblings. This prevents one transient group from being inserted in the
+  // middle of another.
+  FindCommonTransientAncestor(child, target);
+
+  // When stacking above skip to the topmost transient descendant of the target.
+  if (*direction == mojom::ORDER_DIRECTION_ABOVE &&
+      !HasTransientAncestor(*child, *target)) {
+    const ServerWindow::Windows& siblings((*child)->parent()->children());
+    size_t target_i =
+        std::find(siblings.begin(), siblings.end(), *target) - siblings.begin();
+    while (target_i + 1 < siblings.size() &&
+           HasTransientAncestor(siblings[target_i + 1], *target)) {
+      ++target_i;
+    }
+    *target = siblings[target_i];
+  }
+
+  return *child != *target;
+}
+
+}  // namespace ws
+}  // namespace mus
diff --git a/components/mus/ws/transient_window_stacking_client.h b/components/mus/ws/transient_window_stacking_client.h
new file mode 100644
index 0000000..e336a7bd
--- /dev/null
+++ b/components/mus/ws/transient_window_stacking_client.h
@@ -0,0 +1,39 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MUS_WS_TRANSIENT_WINDOW_STACKING_CLIENT_H_
+#define COMPONENTS_MUS_WS_TRANSIENT_WINDOW_STACKING_CLIENT_H_
+
+#include "components/mus/ws/window_stacking_client.h"
+
+#include "base/macros.h"
+
+namespace mus {
+namespace ws {
+
+class TransientWindowManager;
+
+class TransientWindowStackingClient : public WindowStackingClient {
+ public:
+  TransientWindowStackingClient();
+  ~TransientWindowStackingClient() override;
+
+  // WindowStackingClient:
+  bool AdjustStacking(ServerWindow** child,
+                      ServerWindow** target,
+                      mojom::OrderDirection* direction) override;
+
+ private:
+  // Purely for DCHECKs.
+  friend class TransientWindowManager;
+
+  static TransientWindowStackingClient* instance_;
+
+  DISALLOW_COPY_AND_ASSIGN(TransientWindowStackingClient);
+};
+
+}  // namespace ws
+}  // namespace mus
+
+#endif  // COMPONENTS_MUS_WS_TRANSIENT_WINDOW_STACKING_CLIENT_H_
diff --git a/components/mus/ws/window_stacking_client.cc b/components/mus/ws/window_stacking_client.cc
new file mode 100644
index 0000000..84ecd16
--- /dev/null
+++ b/components/mus/ws/window_stacking_client.cc
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/mus/ws/window_stacking_client.h"
+
+namespace mus {
+namespace ws {
+
+namespace {
+
+WindowStackingClient* instance = nullptr;
+
+}  // namespace
+
+void SetWindowStackingClient(WindowStackingClient* client) {
+  instance = client;
+}
+
+WindowStackingClient* GetWindowStackingClient() {
+  return instance;
+}
+
+}  // namespace ws
+}  // namespace mus
diff --git a/components/mus/ws/window_stacking_client.h b/components/mus/ws/window_stacking_client.h
new file mode 100644
index 0000000..9c86d55
--- /dev/null
+++ b/components/mus/ws/window_stacking_client.h
@@ -0,0 +1,40 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MUS_WS_WINDOW_STACKING_CLIENT_H_
+#define COMPONENTS_MUS_WS_WINDOW_STACKING_CLIENT_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/mus/public/interfaces/window_tree.mojom.h"
+
+namespace mus {
+namespace ws {
+
+class ServerWindow;
+
+class WindowStackingClient {
+ public:
+  // Invoked from the various Window stacking functions. Allows the
+  // WindowStackingClient to alter the source, target and/or direction to stack.
+  // Returns true if stacking should continue; false if the stacking should not
+  // happen.
+  virtual bool AdjustStacking(ServerWindow** child,
+                              ServerWindow** target,
+                              mojom::OrderDirection* direction) = 0;
+
+ protected:
+  virtual ~WindowStackingClient() {}
+};
+
+// Sets/gets the WindowStackingClient. This does *not* take ownership of
+// |client|. It is assumed the caller will invoke SetWindowStackingClient(NULL)
+// before deleting |client|.
+void SetWindowStackingClient(WindowStackingClient* client);
+WindowStackingClient* GetWindowStackingClient();
+
+}  // namespace ws
+}  // namespace mus
+
+#endif  // COMPONENTS_MUS_WS_WINDOW_STACKING_CLIENT_H_
diff --git a/components/mus/ws/window_utils.cc b/components/mus/ws/window_utils.cc
new file mode 100644
index 0000000..cc70cf8
--- /dev/null
+++ b/components/mus/ws/window_utils.cc
@@ -0,0 +1,50 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/mus/ws/window_utils.h"
+
+#include "components/mus/ws/transient_window_manager.h"
+
+namespace mus {
+namespace ws {
+
+ServerWindow* GetTransientParent(ServerWindow* window) {
+  return const_cast<ServerWindow*>(
+      GetTransientParent(const_cast<const ServerWindow*>(window)));
+}
+
+const ServerWindow* GetTransientParent(const ServerWindow* window) {
+  const TransientWindowManager* manager = TransientWindowManager::Get(window);
+  return manager ? manager->transient_parent() : NULL;
+}
+
+const std::vector<ServerWindow*>& GetTransientChildren(
+    const ServerWindow* window) {
+  const TransientWindowManager* manager = TransientWindowManager::Get(window);
+  if (manager)
+    return manager->transient_children();
+
+  static std::vector<ServerWindow*>* shared = new std::vector<ServerWindow*>;
+  return *shared;
+}
+
+void AddTransientChild(ServerWindow* parent, ServerWindow* child) {
+  TransientWindowManager::GetOrCreate(parent)->AddTransientChild(child);
+}
+
+void RemoveTransientChild(ServerWindow* parent, ServerWindow* child) {
+  TransientWindowManager::Get(parent)->RemoveTransientChild(child);
+}
+
+bool HasTransientAncestor(const ServerWindow* window,
+                          const ServerWindow* ancestor) {
+  const ServerWindow* transient_parent = GetTransientParent(window);
+  if (transient_parent == ancestor)
+    return true;
+  return transient_parent ? HasTransientAncestor(transient_parent, ancestor)
+                          : false;
+}
+
+}  // namespace ws
+}  // namespace mus
diff --git a/components/mus/ws/window_utils.h b/components/mus/ws/window_utils.h
new file mode 100644
index 0000000..12af2ba
--- /dev/null
+++ b/components/mus/ws/window_utils.h
@@ -0,0 +1,37 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MUS_WS_WINDOW_UTILS_H_
+#define COMPONENTS_MUS_WS_WINDOW_UTILS_H_
+
+#include <vector>
+
+namespace mus {
+namespace ws {
+
+class ServerWindow;
+
+// Convenience functions that get the TransientWindowManager for the window and
+// redirect appropriately. These are preferable to calling functions on
+// TransientWindowManager as they handle the appropriate nullptr checks.
+ServerWindow* GetTransientParent(ServerWindow* window);
+
+const ServerWindow* GetTransientParent(const ServerWindow* window);
+
+const std::vector<ServerWindow*>& GetTransientChildren(
+    const ServerWindow* window);
+
+void AddTransientChild(ServerWindow* parent, ServerWindow* child);
+
+void RemoveTransientChild(ServerWindow* parent, ServerWindow* child);
+
+// Returns true if |window| has |ancestor| as a transient ancestor. A transient
+// ancestor is found by following the transient parent chain of the window.
+bool HasTransientAncestor(const ServerWindow* window,
+                          const ServerWindow* ancestor);
+
+}  // namespace ws
+}  // namespace mus
+
+#endif  // COMPONENTS_MUS_WS_WINDOW_UTILS_H_
diff --git a/components/password_manager/content/browser/content_password_manager_driver_factory.cc b/components/password_manager/content/browser/content_password_manager_driver_factory.cc
index ae8478bf..7f6e421 100644
--- a/components/password_manager/content/browser/content_password_manager_driver_factory.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver_factory.cc
@@ -4,7 +4,6 @@
 
 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
 
-#include "base/bind.h"
 #include "base/stl_util.h"
 #include "components/autofill/content/browser/content_autofill_driver.h"
 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
@@ -52,9 +51,9 @@
     : content::WebContentsObserver(web_contents),
       password_client_(password_client),
       autofill_client_(autofill_client) {
-  web_contents->ForEachFrame(
-      base::Bind(&ContentPasswordManagerDriverFactory::CreateDriverForFrame,
-                 base::Unretained(this)));
+  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
+  if (main_frame->IsRenderFrameLive())
+    CreateDriverForFrame(main_frame);
 }
 
 ContentPasswordManagerDriverFactory::~ContentPasswordManagerDriverFactory() {
@@ -107,8 +106,6 @@
 
 void ContentPasswordManagerDriverFactory::CreateDriverForFrame(
     content::RenderFrameHost* render_frame_host) {
-  if (!render_frame_host->IsRenderFrameLive())
-    return;
   DCHECK(!frame_driver_map_[render_frame_host]);
   frame_driver_map_[render_frame_host] = new ContentPasswordManagerDriver(
       render_frame_host, password_client_, autofill_client_);
diff --git a/components/policy/resources/policy_templates_ca.xtb b/components/policy/resources/policy_templates_ca.xtb
index dab01bab..e8910a412f 100644
--- a/components/policy/resources/policy_templates_ca.xtb
+++ b/components/policy/resources/policy_templates_ca.xtb
@@ -153,8 +153,8 @@
       La política s'ha de definir en un URL del qual <ph name="PRODUCT_OS_NAME" /> pugui baixar els Termes i condicions, que han de trobar-se com a text sense format proporcionat com a text/sense format de tipus MIME. No es permet el marcatge.</translation>
 <translation id="1757339646969878244">Configureu les opcions d'accés remot a l'amfitrió d'Escriptori remot de Chrome.
 
-      L'amfitrió d'Escriptori remot de Chrome és un servei natiu que s'executa al
-      dispositiu de destinació que un usuari pot connectar mitjançant aquesta
+      L'amfitrió d'Escriptori remot de Chrome és un servei natiu que s'executa a
+      l'ordinador de destinació, al qual un usuari es pot connectar mitjançant aquesta
       aplicació. El servei natiu s'empaqueta i s'executa per separat
       del navegador <ph name="PRODUCT_NAME" />.
 
diff --git a/components/policy/resources/policy_templates_da.xtb b/components/policy/resources/policy_templates_da.xtb
index 8b28e0a..1dce59b 100644
--- a/components/policy/resources/policy_templates_da.xtb
+++ b/components/policy/resources/policy_templates_da.xtb
@@ -154,7 +154,7 @@
       Politikken skal indstilles til en webadresse, hvorfra <ph name="PRODUCT_OS_NAME" /> kan downloade servicevilkårene. Servicevilkårene skal være almindelig tekst vist som MIME-tekst. Markering er ikke tilladt.</translation>
 <translation id="1757339646969878244">Konfigurerer muligheder for fjernadgang via hosten for Chrome Fjernskrivebord.
 
-      Hosten for Chrome Fjernskrivebord er en indbygget tjeneste, der kører på den målrettede
+      Hosten for Chrome Fjernskrivebord er en indbygget tjeneste, der kører på den 
       maskine, som en bruger kan oprette forbindelse til vha. appen Chrome
       Fjernskrivebord. Den indbyggede tjeneste pakkes og udføres afskilt fra 
       browseren <ph name="PRODUCT_NAME" />.
@@ -546,17 +546,17 @@
         "type": "object",
         "properties": {
           "kind": {
-            "description": "Whether to limit the search of the matching printer to a specific set of printers.",
+            "description": "Hvorvidt søgningen efter en printer, der opfylder attributten skal begrænses til en specifik printeropsætning.",
             "type": {
               "enum": [ "local", "cloud" ]
             }
           },
           "idPattern": {
-            "description": "Regular expression to match printer id.",
+            "description": "Regulært udtryk, som matcher printer-id.",
             "type": "string"
           },
           "namePattern": {
-            "description": "Regular expression to match printer display name.",
+            "description": "Regulært udtryk, som matcher printerens viste navn.",
             "type": "string"
           }
         }
diff --git a/components/policy/resources/policy_templates_es-419.xtb b/components/policy/resources/policy_templates_es-419.xtb
index 19d865f8..5175ba2 100644
--- a/components/policy/resources/policy_templates_es-419.xtb
+++ b/components/policy/resources/policy_templates_es-419.xtb
@@ -155,7 +155,7 @@
 
       El host del Escritorio remoto de Chrome es un servicio nativo que se ejecuta en la máquina de destino a la que un usuario puede conectarse para utilizar la aplicación Escritorio remoto de Chrome. El servicio nativo se empaqueta y se ejecuta en forma separada del navegador <ph name="PRODUCT_NAME" />.
 
-      Ignora estas políticas a menos que el host del Escritorio remoto de Chrome esté instalado.</translation>
+      Estas políticas se ignoran, a menos que el host del Escritorio remoto de Chrome esté instalado.</translation>
 <translation id="1757688868319862958">Permite que <ph name="PRODUCT_NAME" /> ejecute complementos que requieran autorización. Si habilitas esta opción, se ejecutarán siempre los complementos actualizados. Si no se habilita o no se configura esta opción, se solicitará permiso a los usuarios para ejecutar complementos que requieran autorización (complementos que pueden comprometer la seguridad).</translation>
 <translation id="1803646570632580723">Lista de aplicaciones fijas para mostrar en el menú de aplicaciones</translation>
 <translation id="1808715480127969042">Bloquear cookies en estos sitios</translation>
diff --git a/components/policy/resources/policy_templates_fa.xtb b/components/policy/resources/policy_templates_fa.xtb
index a8c78e8..fe194301 100644
--- a/components/policy/resources/policy_templates_fa.xtb
+++ b/components/policy/resources/policy_templates_fa.xtb
@@ -4,7 +4,7 @@
 <translation id="1017967144265860778">مدیریت نیرو در صفحه ورود به سیستم</translation>
 <translation id="1019101089073227242">تنظیم دایرکتوری داده‌های کاربر</translation>
 <translation id="1022361784792428773">شناسه افزونه‌هایی که کاربران نباید آن‌ها را نصب کنند (علامت * برای همه)</translation>
-<translation id="102492767056134033">تنظیم وضعیت صفحه کلید روی صفحه در صفحه ورود به سیستم</translation>
+<translation id="102492767056134033">تنظیم وضعیت صفحه‌کلید روی صفحه در صفحه ورود به سیستم</translation>
 <translation id="1044878202534415707">آمارهای سخت‌افزاری مانند مصرف پردازشگر/رم را گزارش می‌دهد.
 
       اگر روی نادرست تنظیم شود، آمار گزارش نمی‌شود.
@@ -221,7 +221,7 @@
       اگر این خط‌مشی روی درست تنظیم شود، <ph name="PRODUCT_OS_NAME" /> تلاش می‌کند به‌روزرسانی خودکار داده‌های اصلی را از طریق HTTP دانلود کند. اگر این خط‌مشی روی غلط تنظیم شود یا پیکربندی نشود، HTTPS برای دانلود به‌روزرسانی خودکار داده‌های اصلی استفاده می‌شود.</translation>
 <translation id="2006530844219044261">مدیریت نیرو</translation>
 <translation id="201557587962247231">تواتر آپلود گزارش وضعیت دستگاه</translation>
-<translation id="2030905906517501646">کلید میانبر ارائه دهنده جستجوی پیش‌فرض</translation>
+<translation id="2030905906517501646">کلید میان‌بر ارائه دهنده جستجوی پیش‌فرض</translation>
 <translation id="206623763829450685">‏تعیین می‌کند که کدام روش‌های احراز هویت HTTP توسط <ph name="PRODUCT_NAME" /> پشتیبانی می‌شوند.
 
           مقادیر قابل تنظیم عبارتند از «پایه»، «خلاصه»، «ntlm» و «مذاکره». مقادیر چندگانه را با کاما از هم جدا کنید.
@@ -377,9 +377,9 @@
  اگر این قانون تنظیم شود، اقدامی را مشخص می‌کند که وقتی کاربر برای مدت زمان تعیین شده توسط تأخیر عدم فعالیت، بی‌حرکت بماند، <ph name="PRODUCT_OS_NAME" /> انجام می‌دهد. تأخیر عدم فعالیت را می‌توان به‌طور جداگانه پیکربندی کرد.
  اگر این قانون تنظیم نشود، اقدام پیش‌فرض انجام می‌شود، که تعلیق است.
  اگر اقدام تعلیق باشد، می‌توان <ph name="PRODUCT_OS_NAME" /> را به‌طور جداگانه به قفل شدن یا قفل نشدن صفحه نمایش قبل از تعلیق پیکربندی کرد.</translation>
-<translation id="244317009688098048">‏میانبر آزاد صفحه‌کلید برای ورود خودکار به سیستم را به کار می‌اندازد.
+<translation id="244317009688098048">‏میان‌بر آزاد صفحه‌کلید برای ورود خودکار به سیستم را به کار می‌اندازد.
 
-     اگر این خط‌مشی تنظیم نشود یا روی درست تنظیم شود و حساب محلی دستگاه برای ورود خودکار فوری تنظیم شده باشد، <ph name="PRODUCT_OS_NAME" /> می‌تواند از میانبر صفحه‌کلید Ctrl+Alt+S برای رد شدن از ورود خودکار و نمایش صفحه ورود به سیستم استفاده کند.
+     اگر این خط‌مشی تنظیم نشود یا روی درست تنظیم شود و حساب محلی دستگاه برای ورود خودکار فوری تنظیم شده باشد، <ph name="PRODUCT_OS_NAME" /> می‌تواند از میان‌بر صفحه‌کلید Ctrl+Alt+S برای رد شدن از ورود خودکار و نمایش صفحه ورود به سیستم استفاده کند.
 
      اگر این خط‌مشی روی نادرست تنظیم شود، ورود خودکار فوری (در صورت پیکربندی) قابل رد شدن نیست.</translation>
 <translation id="2463365186486772703">زبان برنامه</translation>
@@ -404,7 +404,7 @@
 
       اگر این تنظیم غیرفعال باشد، کاربران نمی‌توانند از <ph name="PRODUCT_NAME" /> چاپ کنند. چاپ در منوی آچار، افزونه‌ها، برنامه‌های جاوااسکریپت، و غیره غیرفعال است. هنوز می‌توان از افزایه‌هایی که هنگام چاپ از <ph name="PRODUCT_NAME" /> می‌گذرند چاپ کرد. برای مثال برنامه‌های Flash خاصی گزینه چاپ را در منوی متن خود دارند که تحت پوشش این خط‌مشی نیست.</translation>
 <translation id="2518231489509538392">اجازه پخش صدا</translation>
-<translation id="2521581787935130926">نمایش میانبر برنامه‌ها در نوار نشانک‌ها</translation>
+<translation id="2521581787935130926">نمایش میان‌بر برنامه‌ها در نوار نشانک‌ها</translation>
 <translation id="2529700525201305165">محدودکردن کاربرانی که مجاز هستند وارد سیستم <ph name="PRODUCT_NAME" /> شوند</translation>
 <translation id="2529880111512635313">پیکربندی فهرست برنامه‌ها و افزونه‌های به‌اجبار نصب‌شده</translation>
 <translation id="253135976343875019">تأخیر هشدار عدم فعالیت هنگامی که دستگاه به برق وصل است</translation>
@@ -726,7 +726,7 @@
 
       اگر این تنظیم روی درست تنظیم شود یا پیکربندی نشود کاربران می‌توانند از همه خروجی‌های صوتی پشتیبانی‌شده در دستگاهشان استفاده کنند.</translation>
 <translation id="3808945828600697669">تعیین فهرست افزایه‌های غیرفعال شده</translation>
-<translation id="3816312845600780067">به کار انداختن میانبر آزاد صفحه‌کلید برای ورود خودکار به سیستم</translation>
+<translation id="3816312845600780067">به کار انداختن میان‌بر آزاد صفحه‌کلید برای ورود خودکار به سیستم</translation>
 <translation id="3820526221169548563">ویژگی دسترس‌پذیری صفحه‌کلید روی صفحه را فعال کنید.
 
           اگر این خط‌مشی روی درست تنظیم شده باشد، صفحه‌کلید روی صفحه همیشه فعال خواهد بود.
@@ -834,11 +834,11 @@
 <translation id="4377599627073874279">به همه سایت‌ها اجازه نمایش تصاویر داده شود</translation>
 <translation id="4389091865841123886">‏تأیید هویت راه دور را با مکانیزم TPM پیکربندی می‌کند.</translation>
 <translation id="4423597592074154136">تنظیم دستی سرور پروکسی</translation>
-<translation id="4429220551923452215">میانبر برنامه‌ها را در نوار نشانک‌ها فعال یا غیرفعال می‌کند.
+<translation id="4429220551923452215">میان‌بر برنامه‌ها را در نوار نشانک‌ها فعال یا غیرفعال می‌کند.
 
-اگر این خط‌مشی تنظیم نشده باشد، کاربر می‌تواند انتخاب کند که می‌خواهد میانبر برنامه‌ها در منوی زمینه نوار نشانک‌ها نشان داده شود یا پنهان شود.
+اگر این خط‌مشی تنظیم نشده باشد، کاربر می‌تواند انتخاب کند که می‌خواهد میان‌بر برنامه‌ها در منوی زمینه نوار نشانک‌ها نشان داده شود یا پنهان شود.
 
-اگر این خط‌مشی پیکربندی شود، کاربر نمی‌تواند آن را تغییر دهد و میانبر برنامه‌ها همیشه نشان داده می‌شود یا هرگز نشان داده نمی‌شود.</translation>
+اگر این خط‌مشی پیکربندی شود، کاربر نمی‌تواند آن را تغییر دهد و میان‌بر برنامه‌ها همیشه نشان داده می‌شود یا هرگز نشان داده نمی‌شود.</translation>
 <translation id="443665821428652897">پاک کردن داده‌های سایت هنگام بستن مرورگر (منسوخ)</translation>
 <translation id="4439336120285389675">‏فهرستی از ویژگی‌های پلتفورم وبی را برای فعال کردن موقتی تعیین می‌کند.
 
@@ -849,7 +849,7 @@
       با اینکه خود این خط مشی در پلتفورم‌های بالا پشتیبانی می‌شود، اما ویژگی‌هایی که فعال می‌کند ممکن است در پلتفورم‌های کمتری پشتیبانی شده باشند. تمام ویژگی‌های منسوخ شده پلتفورم وب قابل فعال کردن مجدد نیستند. فقط آنهایی را می‌توان فعال کرد که در زیر فهرست شده باشند و فقط برای مدتی محدود که برای هر ویژگی متفاوت است، فعال می‌شوند. قالب عمومی برچسب رشته‌ای باید [DeprecatedFeatureName]_EffectiveUntil[yyyymmdd] باشد. به عنوان مرجع می‌توانید هدف تغییر ویژگی‌های پلتفورم وب را در https://bit.ly/blinkintents بخوانید.
       </translation>
 <translation id="4442582539341804154">وقتی دستگاه غیرفعال یا معلق می‌شود، قفل فعال شود</translation>
-<translation id="4445684791305970001">ابزارهای برنامه‌نویسان و کنسول جاوا اسکریپت را غیرفعال می‌کند. اگر این گزینه را فعال کنید، ابزارهای برنامه‌نویس قابل دسترس نخواهند بود و عناصر وب سایت‌ها دیگر نمی‌توانند بازرسی شوند. همه میانبرهای صفحه‌کلید، منو یا منوی درون نوشتاری که ابزارهای برنامه‌نویس یا کنسول جاوا اسکریپت را باز می‌کنند، غیرفعال می‌شوند. تنظیم این گزینه بر روی غیرفعال یا تنظیم نکردن آن به کاربر اجازه می‌دهد تا از ابزارهای برنامه‌نویس و کنسول جاوا اسکریپت استفاده کند.</translation>
+<translation id="4445684791305970001">ابزارهای برنامه‌نویسان و کنسول جاوا اسکریپت را غیرفعال می‌کند. اگر این گزینه را فعال کنید، ابزارهای برنامه‌نویس قابل دسترس نخواهند بود و عناصر وب سایت‌ها دیگر نمی‌توانند بازرسی شوند. همه میان‌برهای صفحه‌کلید، منو یا منوی درون نوشتاری که ابزارهای برنامه‌نویس یا کنسول جاوا اسکریپت را باز می‌کنند، غیرفعال می‌شوند. تنظیم این گزینه بر روی غیرفعال یا تنظیم نکردن آن به کاربر اجازه می‌دهد تا از ابزارهای برنامه‌نویس و کنسول جاوا اسکریپت استفاده کند.</translation>
 <translation id="4467952432486360968">مسدود کردن کوکی‌های شخص ثالث</translation>
 <translation id="4474167089968829729">فعال کردن ذخیره گذرواژه‌ها در مدیر گذرواژه</translation>
 <translation id="4480694116501920047">انجام جستجوی ایمن</translation>
@@ -1352,15 +1352,15 @@
       کانال انتخابی کاربر توسط ‌خط‌مشی ChromeOsReleaseChannel لغو می شود اما اگر کانال ‌خط‌مشی ثبات بیشتری نسبت به کانالی که روی دستگاه نصب شده بود،  داشته باشد، بنابراین کانال فقط پس از اینکه نسخه کانال ثابت تر به شماره نسخه بالاتر نسبت به کانال نسب شده قبلی روی دستگاه برسد، عوض می شود.</translation>
 <translation id="6559057113164934677">به هر سایتی اجازه داده نشود به دوربین و میکروفون من دسترسی داشته باشد</translation>
 <translation id="6561396069801924653">نمایش گزینه‌های دسترس‌پذیری در منوی نوار سیستم</translation>
-<translation id="6565312346072273043">حالت پیش‌فرض ویژگی دسترس‌پذیری صفحه کلید روی صفحه را در صفحه ورود به سیستم تنظیم کنید.
+<translation id="6565312346072273043">حالت پیش‌فرض ویژگی دسترس‌پذیری صفحه‌کلید روی صفحه را در صفحه ورود به سیستم تنظیم کنید.
 
-           اگر این خط‌مشی روی درست تنظیم شود، وقتی صفحه ورود به سیستم نشان داده می‌شود، صفحه کلید روی صفحه فعال می‌شود.
+           اگر این خط‌مشی روی درست تنظیم شود، وقتی صفحه ورود به سیستم نشان داده می‌شود، صفحه‌کلید روی صفحه فعال می‌شود.
 
-          اگر خط‌مشی روی غلط تنظیم شود، وقتی صفحه ورود به سیستم نشان داده می‌شود، صفحه کلید روی صفحه غیرفعال می‌شود.
+          اگر خط‌مشی روی غلط تنظیم شود، وقتی صفحه ورود به سیستم نشان داده می‌شود، صفحه‌کلید روی صفحه غیرفعال می‌شود.
 
-          اگر این خط‌مشی را تنظیم کنید، کاربران می‌توانند با فعال کردن یا غیرفعال کردن صفحه کلید روی صفحه، به‌طور موقت آن را لغو کنند. اما انتخاب کاربردائمی نیست و هر وقت صفحه ورود به سیستم نشان داده شود یا کاربر در صفحه ورود به سیستم برای لحظه‌ای بدون فعالیت باشد، پیش‌فرض بازیابی می‌شود.
+          اگر این خط‌مشی را تنظیم کنید، کاربران می‌توانند با فعال کردن یا غیرفعال کردن صفحه‌کلید روی صفحه، به‌طور موقت آن را لغو کنند. اما انتخاب کاربردائمی نیست و هر وقت صفحه ورود به سیستم نشان داده شود یا کاربر در صفحه ورود به سیستم برای لحظه‌ای بدون فعالیت باشد، پیش‌فرض بازیابی می‌شود.
 
-          اگر این خط‌مشی تنظیم نشده باقی بماند، وقتی صفحه ورود به سیستم ابتدا نشان داده می‌شود، صفحه کلید روی صفحه غیرفعال می‌شود. کاربران می‌توانند هر وقت خواستند صفحه کلید روی صفحه را فعال یا غیرفعال کنند و این وضعیت در صفحه ورود به سیستم بین کاربران ثابت است.</translation>
+          اگر این خط‌مشی تنظیم نشده باقی بماند، وقتی صفحه ورود به سیستم ابتدا نشان داده می‌شود، صفحه‌کلید روی صفحه غیرفعال می‌شود. کاربران می‌توانند هر وقت خواستند صفحه‌کلید روی صفحه را فعال یا غیرفعال کنند و این وضعیت در صفحه ورود به سیستم بین کاربران ثابت است.</translation>
 <translation id="6598235178374410284">تصویر چهره‌نمای کاربر</translation>
 <translation id="6636268606788232221">‏پیکربندی تنظیمات مدیریت نیرو هنگامی که کاربر فعالیتی ندارد.
 
@@ -1980,7 +1980,7 @@
 <translation id="9200828125069750521">‏پارامترهای نشانی وب تصویر که از POST استفاده می‌کند</translation>
 <translation id="9203071022800375458">‏گرفتن عکس صفحه را غیرفعال می‌کند.
 
-      اگر فعال شود عکس‌های صفحه نمی‌توانند با استفاده از میانبرهای صفحه کلید یا APIهای برنامه افزودنی گرفته شوند.
+      اگر فعال شود عکس‌های صفحه نمی‌توانند با استفاده از میان‌برهای صفحه‌کلید یا APIهای برنامه افزودنی گرفته شوند.
 
       اگر غیرفعال باشد یا تعیین نشده باشد، گرفتن عکس صفحه مجاز است.</translation>
 <translation id="922540222991413931">پیکربندی منابع نصب اسکریپت کاربر، برنامه و برنامهٔ افزودنی</translation>
diff --git a/components/policy/resources/policy_templates_hu.xtb b/components/policy/resources/policy_templates_hu.xtb
index 7c66ee49..271e23c 100644
--- a/components/policy/resources/policy_templates_hu.xtb
+++ b/components/policy/resources/policy_templates_hu.xtb
@@ -516,7 +516,7 @@
 
       Ez a beállítás arra szolgál, hogy tesztelési célból engedélyezze a TLS-domainhez kötött tanúsítványbővítményeket. Ezt a kísérleti beállítást a jövőben eltávolítjuk.</translation>
 <translation id="2959898425599642200">Proxy figyelmen kívül hagyásának szabályai</translation>
-<translation id="2960691910306063964">A PIN kód nélküli hitelesítés engedélyezése vagy kikapcsolása a távoli elérésű gazdagépek számára</translation>
+<translation id="2960691910306063964">A PIN-kód nélküli hitelesítés engedélyezése vagy kikapcsolása a távoli elérésű gazdagépek számára</translation>
 <translation id="2976002782221275500">Megadja azt a felhasználói bevitel nélküli időtartamot, amely után a rendszer elsötétíti a képernyőt, ha akkumulátorról működik.
 
           Ha a házirend nullánál nagyobb értékre van állítva, megadja azt az időtartamot, ameddig a felhasználónak tétlennek kell maradnia, mielőtt a(z) <ph name="PRODUCT_OS_NAME" /> elsötétíti a képernyőt.
@@ -1588,7 +1588,7 @@
 <translation id="7260277299188117560">Az egyenrangú kapcsolatok automatikus frissítésének engedélyezése</translation>
 <translation id="7267809745244694722">A médiabillentyűk alapértelmezés szerint a funkcióbillentyűk</translation>
 <translation id="7271085005502526897">Kezdőlap importálása az alapértelmezett böngészőből az első indításkor</translation>
-<translation id="7273823081800296768">Ha ez a beállítás engedélyezve van, vagy nincs konfigurálva, akkor a felhasználók párosíthatják a klienseket és a gazdagépeket a kapcsolódáskor, így nincs szükség minden alkalommal a PIN kód megadására.
+<translation id="7273823081800296768">Ha ez a beállítás engedélyezve van, vagy nincs konfigurálva, akkor a felhasználók párosíthatják a klienseket és a gazdagépeket a kapcsolódáskor, így nincs szükség minden alkalommal a PIN-kód megadására.
 
           Ha a beállítás le van tiltva, akkor ez a funkció nem lesz elérhető.</translation>
 <translation id="7275334191706090484">Kezelt könyvjelzők</translation>
@@ -1676,11 +1676,11 @@
 <translation id="7715711044277116530">Az a százalék, amellyel a képernyő-sötétedési késleltetés skálázódik prezentációs módban</translation>
 <translation id="7717938661004793600">A <ph name="PRODUCT_OS_NAME" /> kisegítő funkcióinak konfigurálása.</translation>
 <translation id="7719251660743813569">Beállítja, hogy a használati mutatókat jelentse-e a szolgáltatás a Google-nak. Ha az értéke igaz, akkor a(z) <ph name="PRODUCT_OS_NAME" /> jelenti a felhasználói mutatókat. Ha nincs beállítva, vagy a beállítás hamis, akkor a rendszer letiltja a mutató jelentését.</translation>
-<translation id="7749402620209366169">Engedélyezi a kétlépcsős azonosítást a távoli hozzáférésű gazdagépekhez a felhasználóspecifikus PIN kód helyett.
+<translation id="7749402620209366169">Engedélyezi a kétlépcsős azonosítást a távoli hozzáférésű gazdagépekhez a felhasználóspecifikus PIN-kód helyett.
 
           Ha a beállítás engedélyezve van, a felhasználóknak érvényes kétlépcsős kódot kell megadniuk a gazdagéphez való hozzáféréshez.
 
-          Ha a beállítás le van tiltva vagy nincs megadva, akkor a kétlépcsős azonosítás nincs engedélyezve, és alapértelmezés szerint a felhasználó által megadott PIN kód szükséges.</translation>
+          Ha a beállítás le van tiltva vagy nincs megadva, akkor a kétlépcsős azonosítás nincs engedélyezve, és alapértelmezés szerint a felhasználó által megadott PIN-kód szükséges.</translation>
 <translation id="7750991880413385988">Új lap oldal megnyitása</translation>
 <translation id="7761526206824804472">Beállít egy vagy több javasolt nyelv- és országkódot egy nyilvános munkamenet számára, ami lehetővé teszi, hogy a felhasználók egyszerűen válasszanak közülük.
 
diff --git a/components/policy/resources/policy_templates_id.xtb b/components/policy/resources/policy_templates_id.xtb
index 9e9b5a0..eb47a52 100644
--- a/components/policy/resources/policy_templates_id.xtb
+++ b/components/policy/resources/policy_templates_id.xtb
@@ -155,7 +155,7 @@
 <translation id="1757339646969878244">Konfigurasi opsi akses jarak jauh di host Chrome Desktop Jarak Jauh
 
       Host Chrome Desktop Jarak Jauh adalah layanan bawaan yang berjalan di
-      mesin target tempat pengguna tersambung menggunakan 
+      mesin target, tempat pengguna dapat tersambung untuk menggunakan 
       aplikasi Chrome Desktop Jarak Jauh.  Layanan bawaan dimasukkan dalam paket dan 
       dijalankan secara terpisah dari browser <ph name="PRODUCT_NAME" />.
 
diff --git a/components/policy/resources/policy_templates_iw.xtb b/components/policy/resources/policy_templates_iw.xtb
index 58a3b9e..9bfc830 100644
--- a/components/policy/resources/policy_templates_iw.xtb
+++ b/components/policy/resources/policy_templates_iw.xtb
@@ -149,12 +149,12 @@
       אם המדיניות לא מוגדרת, לא מוצגים תנאים והגבלות.
 
       יש להגדיר את המדיניות ככתובת אתר שממנה <ph name="PRODUCT_OS_NAME" /> יכול להוריד את התנאים וההגבלות. התנאים וההגבלות חייבים להיות בטקסט פשוט ומוצגים כסוג MIME טקסט/פשוט. השימוש בסימון אסור.</translation>
-<translation id="1757339646969878244">‏הגדר אפשרויות לגישה מרחוק במארח שולחן עבודה מרוחק של Chrome.
+<translation id="1757339646969878244">‏מגדירה אפשרויות לגישה מרחוק במארח שולחן עבודה מרוחק של Chrome.
 
-מארח שולחן עבודה מרוחק של Chrome הוא שירות מקורי הפועל במכונת היעד שמשתמש יכול להתחבר אליו על ידי אפליקציית שולחן עבודה מרוחק של Chrome. השירות המקורי נארז ומופעל בנפרד מהדפדפן של <ph name="PRODUCT_NAME" />.
+מארח שולחן עבודה מרוחק של Chrome הוא שירות ייעודי שפועל במחשב היעד. המשתמש יכול להתחבר לשירות באמצעות אפליקציית שולחן עבודה מרוחק של Chrome. השירות הייעודי נארז ופועל בנפרד מהדפדפן של <ph name="PRODUCT_NAME" />.
 
-כללי מדיניות אלה אינם תקפים אלא אם כן הותקן
-מארח שולחן עבודה מרוחק של Chrome.</translation>
+אם לא הותקן  מארח שולחן עבודה מרוחק של Chrome,
+המערכת מתעלמת ממדיניות זו.</translation>
 <translation id="1757688868319862958">מאפשר ל-<ph name="PRODUCT_NAME" /> להפעיל יישומי פלאגין שדורשים אישור. אם תאפשר הגדרה זו, יישומי פלאגין שתוקפם לא פג יפעלו תמיד. אם הגדרה זו תושבת או לא תוגדר, משתמשים יתבקשו לאשר את ההפעלה של יישומי פלאגין שדורשים אישור. מדובר ביישומי פלאגין שעלולים לפגוע באבטחה.</translation>
 <translation id="1803646570632580723">רשימת יישומים מוצמדים שיש להציג במפעיל</translation>
 <translation id="1808715480127969042">‏חסום קובצי Cookie באתרים אלה</translation>
diff --git a/components/policy/resources/policy_templates_ko.xtb b/components/policy/resources/policy_templates_ko.xtb
index 6a55734..4bb4e1f 100644
--- a/components/policy/resources/policy_templates_ko.xtb
+++ b/components/policy/resources/policy_templates_ko.xtb
@@ -169,10 +169,10 @@
       이 정책이 설정되어 있지 않으면 서비스 약관이 표시되지 않습니다.
 
       정책은 <ph name="PRODUCT_OS_NAME" />에서 서비스 약관을 다운로드할 수 있는 URL로 설정되어야 합니다. 서비스 약관은 일반 텍스트여야 하며 MIME 유형 text/plain으로 제공됩니다. 마크업은 허용되지 않습니다.</translation>
-<translation id="1757339646969878244">Chrome 원격 데스크톱 호스트에서 원격 액세스 옵션을 구성합니다.
+<translation id="1757339646969878244">Chrome 원격 데스크톱 호스트의 원격 액세스 옵션을 설정합니다.
 
       Chrome 원격 데스크톱 호스트는 사용자가
-      Chrome 원격 데스크톱 애플리케이션을 사용하기 위해
+      Chrome 원격 데스크톱 애플리케이션을 사용해
       연결할 수 있는 대상 기기에서 실행되는 기본 서비스입니다.
       이 기본 서비스는 <ph name="PRODUCT_NAME" /> 브라우저와는 별도로 패키징 및 실행됩니다.
 
diff --git a/components/policy/resources/policy_templates_mr.xtb b/components/policy/resources/policy_templates_mr.xtb
index d69836b..0eb40ea 100644
--- a/components/policy/resources/policy_templates_mr.xtb
+++ b/components/policy/resources/policy_templates_mr.xtb
@@ -164,7 +164,7 @@
       धोरण एका URL वर सेट केले जावे ज्यावरून <ph name="PRODUCT_OS_NAME" /> सेवा अटी डाउनलोड करू शकते. MIME प्रकारच्या मजकूर/साध्या रुपात दिलेल्या सेवा अटी ह्या साधा मजकूर असणे आवश्यक आहे. कोणत्याही मार्कअपला अनुमती नाही.</translation>
 <translation id="1757339646969878244">Chrome दूरस्थ डेस्कटॉप होस्टमध्‍ये दूरस्थ प्रवेश पर्याय कॉन्फिगर करा.
 
-  वापरकर्ता Chrome दूरस्थ डेस्कटॉप अनुप्रयोग वापरून कनेक्‍ट करतो त्या लक्ष्य मशीनवर चालणारी Chrome दूरस्थ डेस्कटॉप ही मूळ सेवा आहे. मूळ सेवा <ph name="PRODUCT_NAME" /> ब्राउझरपेक्षा विभक्तपणे पॅकेज केली जाते आणि
+  वापरकर्ता Chrome दूरस्थ डेस्कटॉप अनुप्रयोग वापरून कनेक्‍ट करतो त्या लक्ष्य मशीनवर चालणारी Chrome दूरस्थ डेस्कटॉप होस्ट ही मूळ सेवा आहे. मूळ सेवा <ph name="PRODUCT_NAME" /> ब्राउझरपेक्षा विभक्तपणे पॅकेज केली जाते आणि
       अंमलात आणली जाते.
 
       Chrome दूरस्थ डेस्कटॉप होस्ट स्थापित केला जाईपर्यंत
diff --git a/components/policy/resources/policy_templates_sk.xtb b/components/policy/resources/policy_templates_sk.xtb
index 50ce62b0..02a2c94 100644
--- a/components/policy/resources/policy_templates_sk.xtb
+++ b/components/policy/resources/policy_templates_sk.xtb
@@ -171,7 +171,7 @@
 <translation id="1757339646969878244">Konfigurácia možností vzdialeného prístupu v hostiteľovi Vzdialenej plochy Chrome.
 
       Hostiteľ Vzdialenej plochy Chrome je natívna služba spustená na cieľovom
-      zariadení, ku ktorému sa môže používateľ prihlásiť, aby mohol používať
+      zariadení, na ktorom sa môže používateľ prihlásiť, aby mohol používať
       aplikáciu Vzdialená plocha Chrome. Táto natívna služba je súčasťou
       samostatného balíka a spúšťa sa oddelene od prehliadača <ph name="PRODUCT_NAME" />.
 
diff --git a/components/policy/resources/policy_templates_sw.xtb b/components/policy/resources/policy_templates_sw.xtb
index dce8caaa..43ca4af 100644
--- a/components/policy/resources/policy_templates_sw.xtb
+++ b/components/policy/resources/policy_templates_sw.xtb
@@ -163,7 +163,7 @@
       Iwapo sera hii haitawekwa, sheria na masharti hayataonyeshwa.
 
       Sera itawekwa kwenye URL ambapo <ph name="PRODUCT_OS_NAME" /> inaweza kupakua Sheria na masharti. Lazima Sheria na Masharti yawe maandishi matupu, yawe kama maandishi ya kuandika/matupu ya MIME. Markup hairuhusiwi.</translation>
-<translation id="1757339646969878244">Sanidi chaguo za idhini ya kufikia kwa mbali katika seva pangishi ya Programu ya Chrome ya Ufikiaji wa Kompyuta kutoka Mbali.
+<translation id="1757339646969878244">Weka chaguo za idhini ya kufikia kwa mbali katika seva pangishi ya Programu ya Chrome ya Ufikiaji wa Kompyuta kutoka Mbali.
 
       Seva pangishi ya Programu ya Chrome ya Ufikiaji wa Kompyuta kutoka Mbali ni huduma ya ndani inayotumika kwenye mashine lengwa ambayo mtumiaji anaweza kuunganisha kwayo kwa kutumia Programu ya Chrome ya Ufikiaji wa Kompyuta kutoka Mbali.  Huduma ya ndani inarembeshwa na kutekelezwa tofauti na kivinajri cha <ph name="PRODUCT_NAME" />.
 
diff --git a/components/policy/resources/policy_templates_ta.xtb b/components/policy/resources/policy_templates_ta.xtb
index b31a888..ea795ed 100644
--- a/components/policy/resources/policy_templates_ta.xtb
+++ b/components/policy/resources/policy_templates_ta.xtb
@@ -146,7 +146,7 @@
       இந்தக் கொள்கை <ph name="PRODUCT_OS_NAME" /> சேவை விதிமுறைகளைப் பதிவிறக்கும் URL க்கு அமைக்கப்படும். சேவை விதிமுறைகளானது எளிய உரையாகவும், MIME வகை உரை/எளிதாக வழங்கப்பட வேண்டும். எந்த மார்க்-அப்பும் அனுமதிக்கப்படவில்லை.</translation>
 <translation id="1757339646969878244">Chrome தொலைநிலை டெஸ்டாப் ஹோஸ்ட்டில் தொலைநிலை அணுகல் விருப்பத்தேர்வுகளை உள்ளமைக்கும்.
 
-      Chrome தொலைநிலை டெஸ்க்டாப் ஹோஸ்ட் என்பது Chrome தொலைநிலை டெஸ்க்டாப் பயன்பாட்டைப் பயன்படுத்திப் பயனர் இணைக்கக்கூடிய இலக்குக் கணினியில் இயங்கும் நேட்டிவ் சேவையாகும்.  நேட்டிவ் சேவையானது <ph name="PRODUCT_NAME" /> உலாவியிலிருந்து தொகுக்கப்பட்டு தனியாகச் செயல்படுத்தப்படுவதாகும்.
+      Chrome தொலைநிலை டெஸ்க்டாப் ஹோஸ்ட் என்பது Chrome தொலைநிலை டெஸ்க்டாப் பயன்பாட்டைப் பயன்படுத்திப் பயனர் இணைக்கக்கூடிய இலக்குக் கணினியில் இயங்கும் நேட்டிவ் சேவையாகும்.  நேட்டிவ் சேவையானது <ph name="PRODUCT_NAME" /> உலாவியைச் சாராமல், தனிப்பட்டதாகத் தொகுக்கப்பட்டு செயல்படுத்தப்படுவதாகும்.
 
       Chrome தொலைநிலை டெஸ்க்டாப் ஹோஸ்ட்
       நிறுவப்படும் வரை இந்தக் கொள்கைகள் புறக்கணிக்கப்படும்.</translation>
diff --git a/components/policy/resources/policy_templates_te.xtb b/components/policy/resources/policy_templates_te.xtb
index 446eaa5..ce4a43cb 100644
--- a/components/policy/resources/policy_templates_te.xtb
+++ b/components/policy/resources/policy_templates_te.xtb
@@ -155,7 +155,7 @@
 <translation id="1757339646969878244">Chrome రిమోట్ డెస్క్‌టాప్ హోస్ట్‌లో రిమోట్ ప్రాప్యత ఎంపికలను కాన్ఫిగర్ చేస్తుంది.
 
       Chrome రిమోట్ డెస్క్‌టాప్ హోస్ట్ అనేది వినియోగదారు Chrome రిమోట్ డెస్క్‌టాప్
-      అప్లికేషన్ ఉపయోగించి కనెక్ట్ కావాలనుకుంటున్న లక్ష్య మెషీన్‌లో అమలయ్యే స్థానిక
+      అనువర్తనాన్ని ఉపయోగించి కనెక్ట్ కావాలనుకుంటున్న లక్ష్య మెషీన్‌లో అమలయ్యే స్థానిక
       సేవ.  స్థానిక సేవ ప్యాకేజీ చేయబడి ఉంటుంది మరియు <ph name="PRODUCT_NAME" /> బ్రౌజర్ నుండి
       వేరుగా అమలు చేయబడుతుంది.
 
diff --git a/components/policy/resources/policy_templates_th.xtb b/components/policy/resources/policy_templates_th.xtb
index 23b994b..2c89c4a 100644
--- a/components/policy/resources/policy_templates_th.xtb
+++ b/components/policy/resources/policy_templates_th.xtb
@@ -155,7 +155,7 @@
 
       โฮสต์ Chrome Remote Desktop คือบริการแบบเนทีฟที่ทำงานบนอุปกรณ์เป้าหมาย
       ซึ่งผู้ใช้สามารถเชื่อมต่อโดยใช้แอปพลิเคชัน Chrome Remote Desktop
-      บริการแบบเนทีฟนี้จะรวมอยู่ในแพ็กเกจและดำเนินการแยกจาก
+      บริการแบบเนทีฟนี้จะรวมอยู่ในแพ็กเกจและมีการดำเนินการแยกจาก
       เบราว์เซอร์ <ph name="PRODUCT_NAME" />
 
       ระบบจะไม่สนใจนโยบายเหล่านี้หาก
diff --git a/components/policy/resources/policy_templates_vi.xtb b/components/policy/resources/policy_templates_vi.xtb
index 124a0eef..7cf937dd 100644
--- a/components/policy/resources/policy_templates_vi.xtb
+++ b/components/policy/resources/policy_templates_vi.xtb
@@ -176,8 +176,8 @@
       Desktop.  Dịch vụ gốc được đóng gói và thực hiện riêng từ
       trình duyệt <ph name="PRODUCT_NAME" />.
 
-      Có thể bỏ qua các chính sách này trừ khi
-      bạn cài đặt máy chủ Chrome Remote Desktop.</translation>
+      Bạn có thể bỏ qua các chính sách này nếu
+      bạn chưa cài đặt máy chủ Chrome Remote Desktop.</translation>
 <translation id="1757688868319862958">Cho phép <ph name="PRODUCT_NAME" /> chạy plugin yêu cầu ủy quyền.
 
       Nếu bạn bật cài đặt này, plugin không bị lỗi thời sẽ luôn chạy.
diff --git a/components/safe_browsing_db.gypi b/components/safe_browsing_db.gypi
index c5cec12c..a874bfa 100644
--- a/components/safe_browsing_db.gypi
+++ b/components/safe_browsing_db.gypi
@@ -16,8 +16,8 @@
         # Note: sources list duplicated in GN build.
         'safe_browsing_db/prefix_set.h',
         'safe_browsing_db/prefix_set.cc',
-        'safe_browsing_db/safe_browsing_db_util.h',
-        'safe_browsing_db/safe_browsing_db_util.cc',
+        'safe_browsing_db/util.h',
+        'safe_browsing_db/util.cc',
       ],
       'include_dirs': [
         '..',
diff --git a/components/safe_browsing_db/BUILD.gn b/components/safe_browsing_db/BUILD.gn
index 4147fe9..f823af6 100644
--- a/components/safe_browsing_db/BUILD.gn
+++ b/components/safe_browsing_db/BUILD.gn
@@ -5,7 +5,7 @@
 group("safe_browsing_db") {
   deps = [
     ":prefix_set",
-    ":safe_browsing_db_util",
+    ":util",
   ]
 }
 
@@ -19,26 +19,30 @@
   ]
 }
 
-source_set("safe_browsing_db_util") {
+source_set("util") {
   sources = [
-    "safe_browsing_db_util.cc",
-    "safe_browsing_db_util.h",
+    "util.cc",
+    "util.h",
   ]
   deps = [
     "//base",
     "//crypto",
   ]
+  if (is_win) {
+    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+    cflags = [ "/wd4267" ]  # Conversion from size_t to 'type'.
+  }
 }
 
 source_set("unit_tests") {
   testonly = true
   sources = [
     "prefix_set_unittest.cc",
-    "safe_browsing_db_util_unittest.cc",
+    "util_unittest.cc",
   ]
   deps = [
     ":prefix_set",
-    ":safe_browsing_db_util",
+    ":util",
     "//base",
     "//testing/gtest",
   ]
diff --git a/components/safe_browsing_db/DEPS b/components/safe_browsing_db/DEPS
index 4ef4138e4..12af900 100644
--- a/components/safe_browsing_db/DEPS
+++ b/components/safe_browsing_db/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   "+crypto",
+  "+net",
 ]
diff --git a/components/safe_browsing_db/prefix_set.h b/components/safe_browsing_db/prefix_set.h
index 433da66..5517105c 100644
--- a/components/safe_browsing_db/prefix_set.h
+++ b/components/safe_browsing_db/prefix_set.h
@@ -55,7 +55,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "components/safe_browsing_db/safe_browsing_db_util.h"
+#include "components/safe_browsing_db/util.h"
 
 namespace base {
 class FilePath;
diff --git a/components/safe_browsing_db/prefix_set_unittest.cc b/components/safe_browsing_db/prefix_set_unittest.cc
index b980e71..08f639a9 100644
--- a/components/safe_browsing_db/prefix_set_unittest.cc
+++ b/components/safe_browsing_db/prefix_set_unittest.cc
@@ -19,7 +19,7 @@
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "components/safe_browsing_db/safe_browsing_db_util.h"
+#include "components/safe_browsing_db/util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
diff --git a/components/safe_browsing_db/util.cc b/components/safe_browsing_db/util.cc
new file mode 100644
index 0000000..8d95b9c
--- /dev/null
+++ b/components/safe_browsing_db/util.cc
@@ -0,0 +1,371 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/safe_browsing_db/util.h"
+
+#include "base/strings/string_util.h"
+#include "crypto/sha2.h"
+#include "net/base/escape.h"
+#include "url/gurl.h"
+#include "url/url_util.h"
+
+// Utility functions -----------------------------------------------------------
+
+namespace {
+bool IsKnownList(const std::string& name) {
+  for (size_t i = 0; i < arraysize(safe_browsing::kAllLists); ++i) {
+    if (!strcmp(safe_browsing::kAllLists[i], name.c_str())) {
+      return true;
+    }
+  }
+  return false;
+}
+}  // namespace
+
+
+// SBCachedFullHashResult ------------------------------------------------------
+
+SBCachedFullHashResult::SBCachedFullHashResult() {}
+
+SBCachedFullHashResult::SBCachedFullHashResult(
+    const base::Time& in_expire_after)
+    : expire_after(in_expire_after) {}
+
+SBCachedFullHashResult::~SBCachedFullHashResult() {}
+
+
+namespace safe_browsing {
+
+// Listnames that browser can process.
+const char kMalwareList[] = "goog-malware-shavar";
+const char kPhishingList[] = "goog-phish-shavar";
+const char kBinUrlList[] = "goog-badbinurl-shavar";
+const char kCsdWhiteList[] = "goog-csdwhite-sha256";
+const char kDownloadWhiteList[] = "goog-downloadwhite-digest256";
+const char kExtensionBlacklist[] = "goog-badcrxids-digestvar";
+const char kIPBlacklist[] = "goog-badip-digest256";
+const char kUnwantedUrlList[] = "goog-unwanted-shavar";
+const char kInclusionWhitelist[] = "goog-csdinclusionwhite-sha256";
+
+const char* kAllLists[9] = {
+    kMalwareList,
+    kPhishingList,
+    kBinUrlList,
+    kCsdWhiteList,
+    kDownloadWhiteList,
+    kExtensionBlacklist,
+    kIPBlacklist,
+    kUnwantedUrlList,
+    kInclusionWhitelist,
+};
+
+ListType GetListId(const base::StringPiece& name) {
+  ListType id;
+  if (name == kMalwareList) {
+    id = MALWARE;
+  } else if (name == kPhishingList) {
+    id = PHISH;
+  } else if (name == kBinUrlList) {
+    id = BINURL;
+  } else if (name == kCsdWhiteList) {
+    id = CSDWHITELIST;
+  } else if (name == kDownloadWhiteList) {
+    id = DOWNLOADWHITELIST;
+  } else if (name == kExtensionBlacklist) {
+    id = EXTENSIONBLACKLIST;
+  } else if (name == kIPBlacklist) {
+    id = IPBLACKLIST;
+  } else if (name == kUnwantedUrlList) {
+    id = UNWANTEDURL;
+  } else if (name == kInclusionWhitelist) {
+    id = INCLUSIONWHITELIST;
+  } else {
+    id = INVALID;
+  }
+  return id;
+}
+
+bool GetListName(ListType list_id, std::string* list) {
+  switch (list_id) {
+    case MALWARE:
+      *list = kMalwareList;
+      break;
+    case PHISH:
+      *list = kPhishingList;
+      break;
+    case BINURL:
+      *list = kBinUrlList;
+      break;
+    case CSDWHITELIST:
+      *list = kCsdWhiteList;
+      break;
+    case DOWNLOADWHITELIST:
+      *list = kDownloadWhiteList;
+      break;
+    case EXTENSIONBLACKLIST:
+      *list = kExtensionBlacklist;
+      break;
+    case IPBLACKLIST:
+      *list = kIPBlacklist;
+      break;
+    case UNWANTEDURL:
+      *list = kUnwantedUrlList;
+      break;
+    case INCLUSIONWHITELIST:
+      *list = kInclusionWhitelist;
+      break;
+    default:
+      return false;
+  }
+  DCHECK(IsKnownList(*list));
+  return true;
+}
+
+
+SBFullHash SBFullHashForString(const base::StringPiece& str) {
+  SBFullHash h;
+  crypto::SHA256HashString(str, &h.full_hash, sizeof(h.full_hash));
+  return h;
+}
+
+SBFullHash StringToSBFullHash(const std::string& hash_in) {
+  DCHECK_EQ(crypto::kSHA256Length, hash_in.size());
+  SBFullHash hash_out;
+  memcpy(hash_out.full_hash, hash_in.data(), crypto::kSHA256Length);
+  return hash_out;
+}
+
+std::string SBFullHashToString(const SBFullHash& hash) {
+  DCHECK_EQ(crypto::kSHA256Length, sizeof(hash.full_hash));
+  return std::string(hash.full_hash, sizeof(hash.full_hash));
+}
+
+
+std::string Unescape(const std::string& url) {
+  std::string unescaped_str(url);
+  std::string old_unescaped_str;
+  const int kMaxLoopIterations = 1024;
+  int loop_var = 0;
+  do {
+    old_unescaped_str = unescaped_str;
+    unescaped_str = net::UnescapeURLComponent(
+        old_unescaped_str, net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS |
+                               net::UnescapeRule::SPACES |
+                               net::UnescapeRule::URL_SPECIAL_CHARS);
+  } while (unescaped_str != old_unescaped_str && ++loop_var <=
+           kMaxLoopIterations);
+
+  return unescaped_str;
+}
+
+std::string Escape(const std::string& url) {
+  std::string escaped_str;
+  const char* kHexString = "0123456789ABCDEF";
+  for (size_t i = 0; i < url.length(); i++) {
+    unsigned char c = static_cast<unsigned char>(url[i]);
+    if (c <= ' ' || c > '~' || c == '#' || c == '%') {
+      escaped_str.push_back('%');
+      escaped_str.push_back(kHexString[c >> 4]);
+      escaped_str.push_back(kHexString[c & 0xf]);
+    } else {
+      escaped_str.push_back(c);
+    }
+  }
+
+  return escaped_str;
+}
+
+std::string RemoveConsecutiveChars(const std::string& str, const char c) {
+  std::string output(str);
+  std::string string_to_find;
+  std::string::size_type loc = 0;
+  string_to_find.append(2, c);
+  while ((loc = output.find(string_to_find, loc)) != std::string::npos) {
+    output.erase(loc, 1);
+  }
+
+  return output;
+}
+
+// Canonicalizes url as per Google Safe Browsing Specification.
+// See section 6.1 in
+// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec.
+void CanonicalizeUrl(const GURL& url,
+                     std::string* canonicalized_hostname,
+                     std::string* canonicalized_path,
+                     std::string* canonicalized_query) {
+  DCHECK(url.is_valid());
+
+  // We only canonicalize "normal" URLs.
+  if (!url.IsStandard())
+    return;
+
+  // Following canonicalization steps are excluded since url parsing takes care
+  // of those :-
+  // 1. Remove any tab (0x09), CR (0x0d), and LF (0x0a) chars from url.
+  //    (Exclude escaped version of these chars).
+  // 2. Normalize hostname to 4 dot-seperated decimal values.
+  // 3. Lowercase hostname.
+  // 4. Resolve path sequences "/../" and "/./".
+
+  // That leaves us with the following :-
+  // 1. Remove fragment in URL.
+  GURL url_without_fragment;
+  GURL::Replacements f_replacements;
+  f_replacements.ClearRef();
+  f_replacements.ClearUsername();
+  f_replacements.ClearPassword();
+  url_without_fragment = url.ReplaceComponents(f_replacements);
+
+  // 2. Do URL unescaping until no more hex encoded characters exist.
+  std::string url_unescaped_str(Unescape(url_without_fragment.spec()));
+  url::Parsed parsed;
+  url::ParseStandardURL(url_unescaped_str.data(), url_unescaped_str.length(),
+                        &parsed);
+
+  // 3. In hostname, remove all leading and trailing dots.
+  const std::string host =
+      (parsed.host.len > 0)
+          ? url_unescaped_str.substr(parsed.host.begin, parsed.host.len)
+          : std::string();
+  std::string host_without_end_dots;
+  base::TrimString(host, ".", &host_without_end_dots);
+
+  // 4. In hostname, replace consecutive dots with a single dot.
+  std::string host_without_consecutive_dots(RemoveConsecutiveChars(
+      host_without_end_dots, '.'));
+
+  // 5. In path, replace runs of consecutive slashes with a single slash.
+  std::string path =
+      (parsed.path.len > 0)
+          ? url_unescaped_str.substr(parsed.path.begin, parsed.path.len)
+          : std::string();
+  std::string path_without_consecutive_slash(RemoveConsecutiveChars(path, '/'));
+
+  url::Replacements<char> hp_replacements;
+  hp_replacements.SetHost(
+      host_without_consecutive_dots.data(),
+      url::Component(0, host_without_consecutive_dots.length()));
+  hp_replacements.SetPath(
+      path_without_consecutive_slash.data(),
+      url::Component(0, path_without_consecutive_slash.length()));
+
+  std::string url_unescaped_with_can_hostpath;
+  url::StdStringCanonOutput output(&url_unescaped_with_can_hostpath);
+  url::Parsed temp_parsed;
+  url::ReplaceComponents(url_unescaped_str.data(),
+                         url_unescaped_str.length(),
+                         parsed,
+                         hp_replacements,
+                         NULL,
+                         &output,
+                         &temp_parsed);
+  output.Complete();
+
+  // 6. Step needed to revert escaping done in url::ReplaceComponents.
+  url_unescaped_with_can_hostpath = Unescape(url_unescaped_with_can_hostpath);
+
+  // 7. After performing all above steps, percent-escape all chars in url which
+  // are <= ASCII 32, >= 127, #, %. Escapes must be uppercase hex characters.
+  std::string escaped_canon_url_str(Escape(url_unescaped_with_can_hostpath));
+  url::Parsed final_parsed;
+  url::ParseStandardURL(escaped_canon_url_str.data(),
+                        escaped_canon_url_str.length(),
+                        &final_parsed);
+
+  if (canonicalized_hostname && final_parsed.host.len > 0) {
+    *canonicalized_hostname =
+        escaped_canon_url_str.substr(final_parsed.host.begin,
+                                     final_parsed.host.len);
+  }
+  if (canonicalized_path && final_parsed.path.len > 0) {
+    *canonicalized_path = escaped_canon_url_str.substr(final_parsed.path.begin,
+                                                       final_parsed.path.len);
+  }
+  if (canonicalized_query && final_parsed.query.len > 0) {
+    *canonicalized_query = escaped_canon_url_str.substr(
+        final_parsed.query.begin, final_parsed.query.len);
+  }
+}
+
+void GenerateHostsToCheck(const GURL& url, std::vector<std::string>* hosts) {
+  hosts->clear();
+
+  std::string canon_host;
+  CanonicalizeUrl(url, &canon_host, NULL, NULL);
+
+  const std::string host = canon_host;  // const sidesteps GCC bugs below!
+  if (host.empty())
+    return;
+
+  // Per the Safe Browsing Protocol v2 spec, we try the host, and also up to 4
+  // hostnames formed by starting with the last 5 components and successively
+  // removing the leading component.  The last component isn't examined alone,
+  // since it's the TLD or a subcomponent thereof.
+  //
+  // Note that we don't need to be clever about stopping at the "real" eTLD --
+  // the data on the server side has been filtered to ensure it will not
+  // blacklist a whole TLD, and it's not significantly slower on our side to
+  // just check too much.
+  //
+  // Also note that because we have a simple blacklist, not some sort of complex
+  // whitelist-in-blacklist or vice versa, it doesn't matter what order we check
+  // these in.
+  const size_t kMaxHostsToCheck = 4;
+  bool skipped_last_component = false;
+  for (std::string::const_reverse_iterator i(host.rbegin());
+       i != host.rend() && hosts->size() < kMaxHostsToCheck; ++i) {
+    if (*i == '.') {
+      if (skipped_last_component)
+        hosts->push_back(std::string(i.base(), host.end()));
+      else
+        skipped_last_component = true;
+    }
+  }
+  hosts->push_back(host);
+}
+
+void GeneratePathsToCheck(const GURL& url, std::vector<std::string>* paths) {
+  paths->clear();
+
+  std::string canon_path;
+  std::string canon_query;
+  CanonicalizeUrl(url, NULL, &canon_path, &canon_query);
+
+  const std::string path = canon_path;   // const sidesteps GCC bugs below!
+  const std::string query = canon_query;
+  if (path.empty())
+    return;
+
+  // Per the Safe Browsing Protocol v2 spec, we try the exact path with/without
+  // the query parameters, and also up to 4 paths formed by starting at the root
+  // and adding more path components.
+  //
+  // As with the hosts above, it doesn't matter what order we check these in.
+  const size_t kMaxPathsToCheck = 4;
+  for (std::string::const_iterator i(path.begin());
+       i != path.end() && paths->size() < kMaxPathsToCheck; ++i) {
+    if (*i == '/')
+      paths->push_back(std::string(path.begin(), i + 1));
+  }
+
+  if (!paths->empty() && paths->back() != path)
+    paths->push_back(path);
+
+  if (!query.empty())
+    paths->push_back(path + "?" + query);
+}
+
+void GeneratePatternsToCheck(const GURL& url, std::vector<std::string>* urls) {
+  std::vector<std::string> hosts, paths;
+  GenerateHostsToCheck(url, &hosts);
+  GeneratePathsToCheck(url, &paths);
+  for (size_t h = 0; h < hosts.size(); ++h) {
+    for (size_t p = 0; p < paths.size(); ++p) {
+      urls->push_back(hosts[h] + paths[p]);
+    }
+  }
+}
+
+}  // namespace safe_browsing
diff --git a/components/safe_browsing_db/util.h b/components/safe_browsing_db/util.h
new file mode 100644
index 0000000..666e081
--- /dev/null
+++ b/components/safe_browsing_db/util.h
@@ -0,0 +1,167 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Utilities for the SafeBrowsing DB code.
+
+#ifndef COMPONENTS_SAFE_BROWSING_DB_UTIL_H_
+#define COMPONENTS_SAFE_BROWSING_DB_UTIL_H_
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/strings/string_piece.h"
+#include "base/time/time.h"
+
+
+class GURL;
+
+// Different types of threats that SafeBrowsing protects against.
+enum SBThreatType {
+  // No threat at all.
+  SB_THREAT_TYPE_SAFE,
+
+  // The URL is being used for phishing.
+  SB_THREAT_TYPE_URL_PHISHING,
+
+  // The URL hosts malware.
+  SB_THREAT_TYPE_URL_MALWARE,
+
+  // The URL hosts unwanted programs.
+  SB_THREAT_TYPE_URL_UNWANTED,
+
+  // The download URL is malware.
+  SB_THREAT_TYPE_BINARY_MALWARE_URL,
+
+  // Url detected by the client-side phishing model.  Note that unlike the
+  // above values, this does not correspond to a downloaded list.
+  SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL,
+
+  // The Chrome extension or app (given by its ID) is malware.
+  SB_THREAT_TYPE_EXTENSION,
+
+  // Url detected by the client-side malware IP list. This IP list is part
+  // of the client side detection model.
+  SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL,
+};
+
+
+// TODO(vakh): Move all these declarations under safe_browsing namespace.
+// A truncated hash's type.
+typedef uint32 SBPrefix;
+
+// A full hash.
+union SBFullHash {
+  char full_hash[32];
+  SBPrefix prefix;
+};
+
+// Used when we get a gethash response.
+struct SBFullHashResult {
+  SBFullHash hash;
+  // TODO(shess): Refactor to allow ListType here.
+  int list_id;
+  std::string metadata;
+};
+
+// Caches individual response from GETHASH request.
+struct SBCachedFullHashResult {
+  SBCachedFullHashResult();
+  explicit SBCachedFullHashResult(const base::Time& in_expire_after);
+  ~SBCachedFullHashResult();
+
+  base::Time expire_after;
+  std::vector<SBFullHashResult> full_hashes;
+};
+
+
+namespace safe_browsing {
+
+// SafeBrowsing list names.
+extern const char kMalwareList[];
+extern const char kPhishingList[];
+// Binary Download list name.
+extern const char kBinUrlList[];
+// SafeBrowsing client-side detection whitelist list name.
+extern const char kCsdWhiteList[];
+// SafeBrowsing download whitelist list name.
+extern const char kDownloadWhiteList[];
+// SafeBrowsing extension list name.
+extern const char kExtensionBlacklist[];
+// SafeBrowsing csd malware IP blacklist name.
+extern const char kIPBlacklist[];
+// SafeBrowsing unwanted URL list.
+extern const char kUnwantedUrlList[];
+// SafeBrowsing off-domain inclusion whitelist list name.
+extern const char kInclusionWhitelist[];
+// This array must contain all Safe Browsing lists.
+extern const char* kAllLists[9];
+
+
+enum ListType {
+  INVALID = -1,
+  MALWARE = 0,
+  PHISH = 1,
+  BINURL = 2,
+  // Obsolete BINHASH = 3,
+  CSDWHITELIST = 4,
+  // SafeBrowsing lists are stored in pairs.  Keep ListType 5
+  // available for a potential second list that we would store in the
+  // csd-whitelist store file.
+  DOWNLOADWHITELIST = 6,
+  // See above comment. Leave 7 available.
+  EXTENSIONBLACKLIST = 8,
+  // See above comment. Leave 9 available.
+  // Obsolete SIDEEFFECTFREEWHITELIST = 10,
+  // See above comment. Leave 11 available.
+  IPBLACKLIST = 12,
+  // See above comment.  Leave 13 available.
+  UNWANTEDURL = 14,
+  // See above comment.  Leave 15 available.
+  INCLUSIONWHITELIST = 16,
+  // See above comment.  Leave 17 available.
+};
+
+
+inline bool SBFullHashEqual(const SBFullHash& a, const SBFullHash& b) {
+  return !memcmp(a.full_hash, b.full_hash, sizeof(a.full_hash));
+}
+
+inline bool SBFullHashLess(const SBFullHash& a, const SBFullHash& b) {
+  return memcmp(a.full_hash, b.full_hash, sizeof(a.full_hash)) < 0;
+}
+
+// Generate full hash for the given string.
+SBFullHash SBFullHashForString(const base::StringPiece& str);
+SBFullHash StringToSBFullHash(const std::string& hash_in);
+std::string SBFullHashToString(const SBFullHash& hash_out);
+
+
+// Maps a list name to ListType.
+ListType GetListId(const base::StringPiece& name);
+
+// Maps a ListId to list name. Return false if fails.
+bool GetListName(ListType list_id, std::string* list);
+
+// Canonicalizes url as per Google Safe Browsing Specification.
+// See section 6.1 in
+// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec.
+void CanonicalizeUrl(const GURL& url, std::string* canonicalized_hostname,
+                     std::string* canonicalized_path,
+                     std::string* canonicalized_query);
+
+// Given a URL, returns all the hosts we need to check.  They are returned
+// in order of size (i.e. b.c is first, then a.b.c).
+void GenerateHostsToCheck(const GURL& url, std::vector<std::string>* hosts);
+
+// Given a URL, returns all the paths we need to check.
+void GeneratePathsToCheck(const GURL& url, std::vector<std::string>* paths);
+
+// Given a URL, returns all the patterns we need to check.
+void GeneratePatternsToCheck(const GURL& url, std::vector<std::string>* urls);
+
+}  // namespace safe_browsing
+
+#endif  // COMPONENTS_SAFE_BROWSING_DB_UTIL_H_
diff --git a/chrome/browser/safe_browsing/safe_browsing_util_unittest.cc b/components/safe_browsing_db/util_unittest.cc
similarity index 74%
rename from chrome/browser/safe_browsing/safe_browsing_util_unittest.cc
rename to components/safe_browsing_db/util_unittest.cc
index 3c875bb..d29bd3f 100644
--- a/chrome/browser/safe_browsing/safe_browsing_util_unittest.cc
+++ b/components/safe_browsing_db/util_unittest.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include <algorithm>
 
 #include "base/strings/stringprintf.h"
-#include "chrome/browser/safe_browsing/safe_browsing_util.h"
+#include "components/safe_browsing_db/util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -20,12 +20,12 @@
 // according to the Safe Browsing spec.
 // See section 6.2 in
 // http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec.
-TEST(SafeBrowsingUtilTest, UrlParsing) {
+TEST(SafeBrowsingDbUtilTest, UrlParsing) {
   std::vector<std::string> hosts, paths;
 
   GURL url("http://a.b.c/1/2.html?param=1");
-  safe_browsing_util::GenerateHostsToCheck(url, &hosts);
-  safe_browsing_util::GeneratePathsToCheck(url, &paths);
+  safe_browsing::GenerateHostsToCheck(url, &hosts);
+  safe_browsing::GeneratePathsToCheck(url, &paths);
   EXPECT_EQ(hosts.size(), static_cast<size_t>(2));
   EXPECT_EQ(paths.size(), static_cast<size_t>(4));
   EXPECT_EQ(hosts[0], "b.c");
@@ -37,8 +37,8 @@
   EXPECT_TRUE(VectorContains(paths, "/"));
 
   url = GURL("http://a.b.c.d.e.f.g/1.html");
-  safe_browsing_util::GenerateHostsToCheck(url, &hosts);
-  safe_browsing_util::GeneratePathsToCheck(url, &paths);
+  safe_browsing::GenerateHostsToCheck(url, &hosts);
+  safe_browsing::GeneratePathsToCheck(url, &paths);
   EXPECT_EQ(hosts.size(), static_cast<size_t>(5));
   EXPECT_EQ(paths.size(), static_cast<size_t>(2));
   EXPECT_EQ(hosts[0], "f.g");
@@ -50,7 +50,7 @@
   EXPECT_TRUE(VectorContains(paths, "/"));
 
   url = GURL("http://a.b/saw-cgi/eBayISAPI.dll/");
-  safe_browsing_util::GeneratePathsToCheck(url, &paths);
+  safe_browsing::GeneratePathsToCheck(url, &paths);
   EXPECT_EQ(paths.size(), static_cast<size_t>(3));
   EXPECT_TRUE(VectorContains(paths, "/saw-cgi/eBayISAPI.dll/"));
   EXPECT_TRUE(VectorContains(paths, "/saw-cgi/"));
@@ -60,7 +60,7 @@
 // Tests the url canonicalization according to the Safe Browsing spec.
 // See section 6.1 in
 // http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec.
-TEST(SafeBrowsingUtilTest, CanonicalizeUrl) {
+TEST(SafeBrowsingDbUtilTest, CanonicalizeUrl) {
   struct {
     const char* input_url;
     const char* expected_canonicalized_hostname;
@@ -265,7 +265,7 @@
     std::string canonicalized_hostname;
     std::string canonicalized_path;
     std::string canonicalized_query;
-    safe_browsing_util::CanonicalizeUrl(url, &canonicalized_hostname,
+    safe_browsing::CanonicalizeUrl(url, &canonicalized_hostname,
         &canonicalized_path, &canonicalized_query);
 
     EXPECT_EQ(tests[i].expected_canonicalized_hostname,
@@ -277,47 +277,63 @@
   }
 }
 
-TEST(SafeBrowsingUtilTest, ListIdListNameConversion) {
+TEST(SafeBrowsingDbUtilTest, ListIdListNameConversion) {
   std::string list_name;
-  EXPECT_FALSE(safe_browsing_util::GetListName(safe_browsing_util::INVALID,
+  EXPECT_FALSE(safe_browsing::GetListName(safe_browsing::INVALID,
                                                &list_name));
-  EXPECT_TRUE(safe_browsing_util::GetListName(safe_browsing_util::MALWARE,
+  EXPECT_TRUE(safe_browsing::GetListName(safe_browsing::MALWARE,
                                               &list_name));
-  EXPECT_EQ(list_name, std::string(safe_browsing_util::kMalwareList));
-  EXPECT_EQ(safe_browsing_util::MALWARE,
-            safe_browsing_util::GetListId(list_name));
+  EXPECT_EQ(list_name, std::string(safe_browsing::kMalwareList));
+  EXPECT_EQ(safe_browsing::MALWARE,
+            safe_browsing::GetListId(list_name));
 
-  EXPECT_TRUE(safe_browsing_util::GetListName(safe_browsing_util::PHISH,
+  EXPECT_TRUE(safe_browsing::GetListName(safe_browsing::PHISH,
                                               &list_name));
-  EXPECT_EQ(list_name, std::string(safe_browsing_util::kPhishingList));
-  EXPECT_EQ(safe_browsing_util::PHISH,
-            safe_browsing_util::GetListId(list_name));
+  EXPECT_EQ(list_name, std::string(safe_browsing::kPhishingList));
+  EXPECT_EQ(safe_browsing::PHISH,
+            safe_browsing::GetListId(list_name));
 
-  EXPECT_TRUE(safe_browsing_util::GetListName(safe_browsing_util::BINURL,
+  EXPECT_TRUE(safe_browsing::GetListName(safe_browsing::BINURL,
                                               &list_name));
-  EXPECT_EQ(list_name, std::string(safe_browsing_util::kBinUrlList));
-  EXPECT_EQ(safe_browsing_util::BINURL,
-            safe_browsing_util::GetListId(list_name));
+  EXPECT_EQ(list_name, std::string(safe_browsing::kBinUrlList));
+  EXPECT_EQ(safe_browsing::BINURL,
+            safe_browsing::GetListId(list_name));
 }
 
 // Since the ids are saved in file, we need to make sure they don't change.
 // Since only the last bit of each id is saved in file together with
 // chunkids, this checks only last bit.
-TEST(SafeBrowsingUtilTest, ListIdVerification) {
-  EXPECT_EQ(0, safe_browsing_util::MALWARE % 2);
-  EXPECT_EQ(1, safe_browsing_util::PHISH % 2);
-  EXPECT_EQ(0, safe_browsing_util::BINURL %2);
+TEST(SafeBrowsingDbUtilTest, ListIdVerification) {
+  EXPECT_EQ(0, safe_browsing::MALWARE % 2);
+  EXPECT_EQ(1, safe_browsing::PHISH % 2);
+  EXPECT_EQ(0, safe_browsing::BINURL %2);
 }
 
-TEST(SafeBrowsingUtilTest, StringToSBFullHashAndSBFullHashToString) {
+TEST(SafeBrowsingDbUtilTest, StringToSBFullHashAndSBFullHashToString) {
   // 31 chars plus the last \0 as full_hash.
   const std::string hash_in = "12345678902234567890323456789012";
-  SBFullHash hash_out = safe_browsing_util::StringToSBFullHash(hash_in);
+  SBFullHash hash_out = safe_browsing::StringToSBFullHash(hash_in);
   EXPECT_EQ(0x34333231U, hash_out.prefix);
   EXPECT_EQ(0, memcmp(hash_in.data(), hash_out.full_hash, sizeof(SBFullHash)));
 
-  std::string hash_final = safe_browsing_util::SBFullHashToString(hash_out);
+  std::string hash_final = safe_browsing::SBFullHashToString(hash_out);
   EXPECT_EQ(hash_in, hash_final);
 }
 
+TEST(SafeBrowsingDbUtilTest, FullHashOperators) {
+  const SBFullHash kHash1 = safe_browsing::SBFullHashForString("one");
+  const SBFullHash kHash2 = safe_browsing::SBFullHashForString("two");
+
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(kHash1, kHash1));
+  EXPECT_TRUE(safe_browsing::SBFullHashEqual(kHash2, kHash2));
+  EXPECT_FALSE(safe_browsing::SBFullHashEqual(kHash1, kHash2));
+  EXPECT_FALSE(safe_browsing::SBFullHashEqual(kHash2, kHash1));
+
+  EXPECT_FALSE(safe_browsing::SBFullHashLess(kHash1, kHash2));
+  EXPECT_TRUE(safe_browsing::SBFullHashLess(kHash2, kHash1));
+
+  EXPECT_FALSE(safe_browsing::SBFullHashLess(kHash1, kHash1));
+  EXPECT_FALSE(safe_browsing::SBFullHashLess(kHash2, kHash2));
+}
+
 }  // namespace
diff --git a/components/scheduler/base/task_queue_impl.cc b/components/scheduler/base/task_queue_impl.cc
index 1c8dbf4..6517707 100644
--- a/components/scheduler/base/task_queue_impl.cc
+++ b/components/scheduler/base/task_queue_impl.cc
@@ -5,6 +5,7 @@
 #include "components/scheduler/base/task_queue_impl.h"
 
 #include "components/scheduler/base/task_queue_manager.h"
+#include "components/scheduler/base/task_queue_manager_delegate.h"
 
 namespace scheduler {
 namespace internal {
@@ -103,7 +104,7 @@
   base::AutoLock lock(any_thread_lock_);
   if (!any_thread().task_queue_manager)
     return false;
-  LazyNow lazy_now(any_thread().task_queue_manager->tick_clock());
+  LazyNow lazy_now(any_thread().task_queue_manager->delegate().get());
   return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time,
                                TaskType::NORMAL);
 }
@@ -116,7 +117,7 @@
   base::AutoLock lock(any_thread_lock_);
   if (!any_thread().task_queue_manager)
     return false;
-  LazyNow lazy_now(any_thread().task_queue_manager->tick_clock());
+  LazyNow lazy_now(any_thread().task_queue_manager->delegate().get());
   base::TimeTicks desired_run_time;
   if (delay > base::TimeDelta())
     desired_run_time = lazy_now.Now() + delay;
@@ -321,7 +322,7 @@
   if (!any_thread().task_queue_manager)
     return;
 
-  LazyNow lazy_now(any_thread().task_queue_manager->tick_clock());
+  LazyNow lazy_now(any_thread().task_queue_manager->delegate().get());
   MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now);
 
   bool was_empty = main_thread_only().work_queue.empty();
diff --git a/components/scheduler/base/task_queue_manager.cc b/components/scheduler/base/task_queue_manager.cc
index f859d0c1d..2f55735 100644
--- a/components/scheduler/base/task_queue_manager.cc
+++ b/components/scheduler/base/task_queue_manager.cc
@@ -171,7 +171,7 @@
   DCHECK(main_thread_checker_.CalledOnValidThread());
   TRACE_EVENT0(disabled_by_default_tracing_category_,
                "TaskQueueManager::UpdateWorkQueues");
-  internal::LazyNow lazy_now(tick_clock());
+  internal::LazyNow lazy_now(delegate().get());
 
   // Move any ready delayed tasks into the incomming queues.
   WakeupReadyDelayedQueues(&lazy_now);
@@ -192,7 +192,7 @@
 void TaskQueueManager::ScheduleDelayedWorkTask(
     scoped_refptr<internal::TaskQueueImpl> queue,
     base::TimeTicks delayed_run_time) {
-  internal::LazyNow lazy_now(tick_clock());
+  internal::LazyNow lazy_now(delegate().get());
   ScheduleDelayedWork(queue.get(), delayed_run_time, &lazy_now);
 }
 
@@ -400,8 +400,9 @@
   return !task_was_run;
 }
 
-base::TickClock* TaskQueueManager::tick_clock() const {
-  return delegate_.get();
+const scoped_refptr<TaskQueueManagerDelegate>& TaskQueueManager::delegate()
+    const {
+  return delegate_;
 }
 
 int TaskQueueManager::GetNextSequenceNumber() {
diff --git a/components/scheduler/base/task_queue_manager.h b/components/scheduler/base/task_queue_manager.h
index 88737a3..002c4bc 100644
--- a/components/scheduler/base/task_queue_manager.h
+++ b/components/scheduler/base/task_queue_manager.h
@@ -100,8 +100,8 @@
   // Note |observer| is expected to outlive the SchedulerHelper.
   void SetObserver(Observer* observer);
 
-  // Returns the TickClock used by the TaskQueueManager.
-  base::TickClock* tick_clock() const;
+  // Returns the delegate used by the TaskQueueManager.
+  const scoped_refptr<TaskQueueManagerDelegate>& delegate() const;
 
  private:
   friend class internal::LazyNow;
diff --git a/components/scheduler/base/task_queue_manager_delegate.h b/components/scheduler/base/task_queue_manager_delegate.h
index a93110e8..b11f7d3 100644
--- a/components/scheduler/base/task_queue_manager_delegate.h
+++ b/components/scheduler/base/task_queue_manager_delegate.h
@@ -29,6 +29,10 @@
   // this.
   virtual void OnNoMoreImmediateWork() = 0;
 
+  // Returns the time as a double which is the number of seconds since epoch
+  // (Jan 1, 1970).  Blink uses this format to represent time.
+  virtual double CurrentTimeSeconds() const = 0;
+
  protected:
   ~TaskQueueManagerDelegate() override {}
 
diff --git a/components/scheduler/base/task_queue_manager_delegate_for_test.cc b/components/scheduler/base/task_queue_manager_delegate_for_test.cc
index d1d2316..fe3d0e5c 100644
--- a/components/scheduler/base/task_queue_manager_delegate_for_test.cc
+++ b/components/scheduler/base/task_queue_manager_delegate_for_test.cc
@@ -51,6 +51,10 @@
   return time_source_->NowTicks();
 }
 
+double TaskQueueManagerDelegateForTest::CurrentTimeSeconds() const {
+  return (time_source_->NowTicks() - base::TimeTicks::UnixEpoch()).InSecondsF();
+}
+
 void TaskQueueManagerDelegateForTest::OnNoMoreImmediateWork() {}
 
 }  // namespace scheduler
diff --git a/components/scheduler/base/task_queue_manager_delegate_for_test.h b/components/scheduler/base/task_queue_manager_delegate_for_test.h
index 390dd90f..2408502 100644
--- a/components/scheduler/base/task_queue_manager_delegate_for_test.h
+++ b/components/scheduler/base/task_queue_manager_delegate_for_test.h
@@ -28,6 +28,7 @@
   bool IsNested() const override;
   base::TimeTicks NowTicks() override;
   void OnNoMoreImmediateWork() override;
+  double CurrentTimeSeconds() const override;
 
  protected:
   ~TaskQueueManagerDelegateForTest() override;
diff --git a/components/scheduler/child/idle_helper.cc b/components/scheduler/child/idle_helper.cc
index 5808cd6..84f6171 100644
--- a/components/scheduler/child/idle_helper.cc
+++ b/components/scheduler/child/idle_helper.cc
@@ -10,6 +10,7 @@
 #include "components/scheduler/base/task_queue.h"
 #include "components/scheduler/base/task_queue_manager.h"
 #include "components/scheduler/child/scheduler_helper.h"
+#include "components/scheduler/child/scheduler_tqm_delegate.h"
 
 namespace scheduler {
 
@@ -139,7 +140,7 @@
     return;
   }
 
-  base::TimeTicks now(helper_->tick_clock()->NowTicks());
+  base::TimeTicks now(helper_->scheduler_tqm_delegate()->NowTicks());
   base::TimeDelta next_long_idle_period_delay;
   IdlePeriodState new_idle_period_state =
       ComputeNewLongIdlePeriodState(now, &next_long_idle_period_delay);
@@ -203,7 +204,8 @@
   if (IsInIdlePeriod(state_.idle_period_state()) &&
       state_.idle_period_state() !=
           IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED &&
-      helper_->tick_clock()->NowTicks() >= state_.idle_period_deadline()) {
+      helper_->scheduler_tqm_delegate()->NowTicks() >=
+          state_.idle_period_deadline()) {
     // If the idle period deadline has now been reached, either end the idle
     // period or trigger a new long-idle period.
     if (IsInLongIdlePeriod(state_.idle_period_state())) {
@@ -238,9 +240,9 @@
     } else {
       // Otherwise ensure that we kick the scheduler at the right time to
       // initiate the next idle period.
-      next_long_idle_period_delay =
-          std::max(base::TimeDelta(), state_.idle_period_deadline() -
-                                          helper_->tick_clock()->NowTicks());
+      next_long_idle_period_delay = std::max(
+          base::TimeDelta(), state_.idle_period_deadline() -
+                                 helper_->scheduler_tqm_delegate()->NowTicks());
     }
     if (next_long_idle_period_delay == base::TimeDelta()) {
       EnableLongIdlePeriod();
@@ -360,7 +362,7 @@
   TRACE_EVENT_CATEGORY_GROUP_ENABLED(tracing_category_, &is_tracing);
   if (is_tracing) {
     base::TimeTicks now(optional_now.is_null()
-                            ? helper_->tick_clock()->NowTicks()
+                            ? helper_->scheduler_tqm_delegate()->NowTicks()
                             : optional_now);
     TraceEventIdlePeriodStateChange(
         new_state, running_idle_task_for_tracing_, idle_period_deadline_, now);
diff --git a/components/scheduler/child/scheduler_helper.cc b/components/scheduler/child/scheduler_helper.cc
index acec8b6..9056e2b 100644
--- a/components/scheduler/child/scheduler_helper.cc
+++ b/components/scheduler/child/scheduler_helper.cc
@@ -44,6 +44,7 @@
 
   task_queue_manager_->SetWorkBatchSize(4);
 
+  DCHECK(task_queue_manager_delegate_);
   task_queue_manager_delegate_->SetDefaultTaskRunner(
       default_task_runner_.get());
 }
@@ -90,8 +91,9 @@
   return task_queue_manager_.get();
 }
 
-base::TickClock* SchedulerHelper::tick_clock() const {
-  return task_queue_manager_->tick_clock();
+const scoped_refptr<SchedulerTqmDelegate>&
+SchedulerHelper::scheduler_tqm_delegate() const {
+  return task_queue_manager_delegate_;
 }
 
 base::TimeTicks SchedulerHelper::NextPendingDelayedTaskRunTime() const {
diff --git a/components/scheduler/child/scheduler_helper.h b/components/scheduler/child/scheduler_helper.h
index a0b8be26..9570f73 100644
--- a/components/scheduler/child/scheduler_helper.h
+++ b/components/scheduler/child/scheduler_helper.h
@@ -83,7 +83,7 @@
   void SetObserver(Observer* observer);
 
   // Accessor methods.
-  base::TickClock* tick_clock() const;
+  const scoped_refptr<SchedulerTqmDelegate>& scheduler_tqm_delegate() const;
   base::TimeTicks NextPendingDelayedTaskRunTime() const;
   bool GetAndClearSystemIsQuiescentBit();
 
diff --git a/components/scheduler/child/scheduler_tqm_delegate_for_test.cc b/components/scheduler/child/scheduler_tqm_delegate_for_test.cc
index 4ff373f..ddd7a3a 100644
--- a/components/scheduler/child/scheduler_tqm_delegate_for_test.cc
+++ b/components/scheduler/child/scheduler_tqm_delegate_for_test.cc
@@ -62,6 +62,10 @@
   return task_runner_->NowTicks();
 }
 
+double SchedulerTqmDelegateForTest::CurrentTimeSeconds() const {
+  return base::Time::Now().ToDoubleT();
+}
+
 void SchedulerTqmDelegateForTest::OnNoMoreImmediateWork() {}
 
 }  // namespace scheduler
diff --git a/components/scheduler/child/scheduler_tqm_delegate_for_test.h b/components/scheduler/child/scheduler_tqm_delegate_for_test.h
index 2d9478f..d7768f3 100644
--- a/components/scheduler/child/scheduler_tqm_delegate_for_test.h
+++ b/components/scheduler/child/scheduler_tqm_delegate_for_test.h
@@ -33,6 +33,7 @@
   bool IsNested() const override;
   base::TimeTicks NowTicks() override;
   void OnNoMoreImmediateWork() override;
+  double CurrentTimeSeconds() const override;
 
   base::SingleThreadTaskRunner* default_task_runner() const {
     return default_task_runner_.get();
diff --git a/components/scheduler/child/scheduler_tqm_delegate_impl.cc b/components/scheduler/child/scheduler_tqm_delegate_impl.cc
index 8057d7e..dbf2c424 100644
--- a/components/scheduler/child/scheduler_tqm_delegate_impl.cc
+++ b/components/scheduler/child/scheduler_tqm_delegate_impl.cc
@@ -62,6 +62,10 @@
   return time_source_->NowTicks();
 }
 
+double SchedulerTqmDelegateImpl::CurrentTimeSeconds() const {
+  return base::Time::Now().ToDoubleT();
+}
+
 void SchedulerTqmDelegateImpl::OnNoMoreImmediateWork() {}
 
 }  // namespace scheduler
diff --git a/components/scheduler/child/scheduler_tqm_delegate_impl.h b/components/scheduler/child/scheduler_tqm_delegate_impl.h
index 23c378c..3f01907 100644
--- a/components/scheduler/child/scheduler_tqm_delegate_impl.h
+++ b/components/scheduler/child/scheduler_tqm_delegate_impl.h
@@ -34,6 +34,7 @@
   bool IsNested() const override;
   base::TimeTicks NowTicks() override;
   void OnNoMoreImmediateWork() override;
+  double CurrentTimeSeconds() const override;
 
  protected:
   ~SchedulerTqmDelegateImpl() override;
diff --git a/components/scheduler/child/virtual_time_tqm_delegate.cc b/components/scheduler/child/virtual_time_tqm_delegate.cc
index 2d7399f..a5aebf1b 100644
--- a/components/scheduler/child/virtual_time_tqm_delegate.cc
+++ b/components/scheduler/child/virtual_time_tqm_delegate.cc
@@ -65,6 +65,10 @@
   return now_;
 }
 
+double VirtualTimeTqmDelegate::CurrentTimeSeconds() const {
+  return (now_ - base::TimeTicks::UnixEpoch()).InSecondsF();
+}
+
 void VirtualTimeTqmDelegate::AdvancedTimeTo(base::TimeTicks now) {
   now_ = now;
   DCHECK_GE(now, now_);
diff --git a/components/scheduler/child/virtual_time_tqm_delegate.h b/components/scheduler/child/virtual_time_tqm_delegate.h
index ba0302a..8a0aae2 100644
--- a/components/scheduler/child/virtual_time_tqm_delegate.h
+++ b/components/scheduler/child/virtual_time_tqm_delegate.h
@@ -36,6 +36,7 @@
   bool IsNested() const override;
   base::TimeTicks NowTicks() override;
   void OnNoMoreImmediateWork() override;
+  double CurrentTimeSeconds() const override;
 
  protected:
   ~VirtualTimeTqmDelegate() override;
diff --git a/components/scheduler/renderer/renderer_scheduler.h b/components/scheduler/renderer/renderer_scheduler.h
index 4f7da03..5f7b0a5 100644
--- a/components/scheduler/renderer/renderer_scheduler.h
+++ b/components/scheduler/renderer/renderer_scheduler.h
@@ -144,6 +144,12 @@
   // received via OnRendererBackgrounded. Defaults to disabled.
   virtual void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) = 0;
 
+  // Returns a double which is the number of seconds since epoch (Jan 1, 1970).
+  virtual double CurrentTimeSeconds() const = 0;
+
+  // Returns a microsecond resolution platform dependant time source.
+  virtual double MonotonicallyIncreasingTimeSeconds() const = 0;
+
  protected:
   RendererScheduler();
   DISALLOW_COPY_AND_ASSIGN(RendererScheduler);
diff --git a/components/scheduler/renderer/renderer_scheduler_impl.cc b/components/scheduler/renderer/renderer_scheduler_impl.cc
index 6f98177e..e06e47a 100644
--- a/components/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/components/scheduler/renderer/renderer_scheduler_impl.cc
@@ -49,7 +49,8 @@
           base::Bind(&RendererSchedulerImpl::UpdatePolicy,
                      base::Unretained(this)),
           helper_.ControlTaskRunner()),
-      main_thread_only_(compositor_task_runner_, helper_.tick_clock()),
+      main_thread_only_(compositor_task_runner_,
+                        helper_.scheduler_tqm_delegate().get()),
       policy_may_need_update_(&any_thread_lock_),
       weak_factory_(this) {
   update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
@@ -252,7 +253,7 @@
   if (helper_.IsShutdown())
     return;
 
-  base::TimeTicks now(helper_.tick_clock()->NowTicks());
+  base::TimeTicks now(helper_.scheduler_tqm_delegate()->NowTicks());
   if (now < MainThreadOnly().estimated_next_frame_begin) {
     // TODO(rmcilroy): Consider reducing the idle period based on the runtime of
     // the next pending delayed tasks (as currently done in for long idle times)
@@ -309,7 +310,7 @@
   // TODO(alexclarke): Should we update policy here?
   TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
       TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
-      this, AsValue(helper_.tick_clock()->NowTicks()));
+      this, AsValue(helper_.scheduler_tqm_delegate()->NowTicks()));
 }
 
 void RendererSchedulerImpl::SetHasVisibleRenderWidgetWithTouchHandler(
@@ -402,7 +403,7 @@
                "RendererSchedulerImpl::DidAnimateForInputOnCompositorThread");
   base::AutoLock lock(any_thread_lock_);
   AnyThread().fling_compositor_escalation_deadline =
-      helper_.tick_clock()->NowTicks() +
+      helper_.scheduler_tqm_delegate()->NowTicks() +
       base::TimeDelta::FromMilliseconds(kFlingEscalationLimitMillis);
 }
 
@@ -410,7 +411,7 @@
     blink::WebInputEvent::Type type,
     InputEventState input_event_state) {
   base::AutoLock lock(any_thread_lock_);
-  base::TimeTicks now = helper_.tick_clock()->NowTicks();
+  base::TimeTicks now = helper_.scheduler_tqm_delegate()->NowTicks();
 
   // TODO(alexclarke): Move WebInputEventTraits where we can access it from here
   // and record the name rather than the integer representation.
@@ -492,7 +493,7 @@
   if (ShouldPrioritizeInputEvent(web_input_event)) {
     base::AutoLock lock(any_thread_lock_);
     AnyThread().user_model.DidFinishProcessingInputEvent(
-        helper_.tick_clock()->NowTicks());
+        helper_.scheduler_tqm_delegate()->NowTicks());
   }
 }
 
@@ -583,7 +584,7 @@
   if (helper_.IsShutdown())
     return;
 
-  base::TimeTicks now = helper_.tick_clock()->NowTicks();
+  base::TimeTicks now = helper_.scheduler_tqm_delegate()->NowTicks();
   policy_may_need_update_.SetWhileLocked(false);
 
   base::TimeDelta expected_use_case_duration;
@@ -885,7 +886,7 @@
   any_thread_lock_.AssertAcquired();
 
   if (optional_now.is_null())
-    optional_now = helper_.tick_clock()->NowTicks();
+    optional_now = helper_.scheduler_tqm_delegate()->NowTicks();
   scoped_refptr<base::trace_event::TracedValue> state =
       new base::trace_event::TracedValue();
 
@@ -965,7 +966,8 @@
 
 void RendererSchedulerImpl::OnIdlePeriodEnded() {
   base::AutoLock lock(any_thread_lock_);
-  AnyThread().last_idle_period_end_time = helper_.tick_clock()->NowTicks();
+  AnyThread().last_idle_period_end_time =
+      helper_.scheduler_tqm_delegate()->NowTicks();
   AnyThread().in_idle_period = false;
   UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
 }
@@ -989,7 +991,7 @@
                "RendererSchedulerImpl::OnNavigationStarted");
   base::AutoLock lock(any_thread_lock_);
   AnyThread().rails_loading_priority_deadline =
-      helper_.tick_clock()->NowTicks() +
+      helper_.scheduler_tqm_delegate()->NowTicks() +
       base::TimeDelta::FromMilliseconds(
           kRailsInitialLoadingPrioritizationMillis);
   ResetForNavigationLocked();
@@ -1025,9 +1027,18 @@
   MainThreadOnly().loading_task_cost_estimator.Clear();
   MainThreadOnly().timer_task_cost_estimator.Clear();
   MainThreadOnly().idle_time_estimator.Clear();
-  AnyThread().user_model.Reset(helper_.tick_clock()->NowTicks());
+  AnyThread().user_model.Reset(helper_.scheduler_tqm_delegate()->NowTicks());
   MainThreadOnly().have_seen_a_begin_main_frame = false;
   UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
 }
 
+double RendererSchedulerImpl::CurrentTimeSeconds() const {
+  return helper_.scheduler_tqm_delegate()->CurrentTimeSeconds();
+}
+
+double RendererSchedulerImpl::MonotonicallyIncreasingTimeSeconds() const {
+  return helper_.scheduler_tqm_delegate()->NowTicks().ToInternalValue() /
+         static_cast<double>(base::Time::kMicrosecondsPerSecond);
+}
+
 }  // namespace scheduler
diff --git a/components/scheduler/renderer/renderer_scheduler_impl.h b/components/scheduler/renderer/renderer_scheduler_impl.h
index 5b5f6e9..cf86ab7 100644
--- a/components/scheduler/renderer/renderer_scheduler_impl.h
+++ b/components/scheduler/renderer/renderer_scheduler_impl.h
@@ -70,6 +70,8 @@
   void SuspendTimerQueue() override;
   void ResumeTimerQueue() override;
   void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) override;
+  double CurrentTimeSeconds() const override;
+  double MonotonicallyIncreasingTimeSeconds() const override;
 
   // RenderWidgetSignals::Observer implementation:
   void SetAllRenderWidgetsHidden(bool hidden) override;
diff --git a/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc b/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc
index c1aa479..ca35441 100644
--- a/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc
+++ b/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.cc
@@ -89,6 +89,10 @@
   return time_source_->NowTicks();
 }
 
+double LazySchedulerMessageLoopDelegateForTests::CurrentTimeSeconds() const {
+  return base::Time::Now().ToDoubleT();
+}
+
 void LazySchedulerMessageLoopDelegateForTests::OnNoMoreImmediateWork() {}
 
 }  // namespace scheduler
diff --git a/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.h b/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.h
index 16c7d98..84fd46d 100644
--- a/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.h
+++ b/components/scheduler/test/lazy_scheduler_message_loop_delegate_for_tests.h
@@ -36,6 +36,7 @@
   bool IsNested() const override;
   base::TimeTicks NowTicks() override;
   void OnNoMoreImmediateWork() override;
+  double CurrentTimeSeconds() const override;
 
  private:
   LazySchedulerMessageLoopDelegateForTests();
diff --git a/components/startup_metric_utils.gypi b/components/startup_metric_utils.gypi
index f70e7a0..55763c8d 100644
--- a/components/startup_metric_utils.gypi
+++ b/components/startup_metric_utils.gypi
@@ -5,7 +5,7 @@
 {
   'targets': [
     {
-      'target_name': 'startup_metric_utils_browser',
+      'target_name': 'startup_metric_utils',
       'type': 'static_library',
       'dependencies': [
         '../base/base.gyp:base',
@@ -14,8 +14,8 @@
         '..',
       ],
       'sources': [
-        'startup_metric_utils/browser/startup_metric_utils.cc',
-        'startup_metric_utils/browser/startup_metric_utils.h',
+        'startup_metric_utils/startup_metric_utils.cc',
+        'startup_metric_utils/startup_metric_utils.h',
       ],
     },
   ],
diff --git a/components/startup_metric_utils/browser/BUILD.gn b/components/startup_metric_utils/BUILD.gn
similarity index 87%
rename from components/startup_metric_utils/browser/BUILD.gn
rename to components/startup_metric_utils/BUILD.gn
index 258e2106..428b2bd 100644
--- a/components/startup_metric_utils/browser/BUILD.gn
+++ b/components/startup_metric_utils/BUILD.gn
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-source_set("browser") {
+source_set("startup_metric_utils") {
   sources = [
     "startup_metric_utils.cc",
     "startup_metric_utils.h",
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/startup_metric_utils.cc
similarity index 99%
rename from components/startup_metric_utils/browser/startup_metric_utils.cc
rename to components/startup_metric_utils/startup_metric_utils.cc
index 3969ed8..74233a3 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/components/startup_metric_utils/startup_metric_utils.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/startup_metric_utils/startup_metric_utils.h"
 
 #include "base/containers/hash_tables.h"
 #include "base/environment.h"
@@ -183,11 +183,11 @@
                                            end_time - begin_time)              \
     TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(                                   \
         "startup", basename, 0,                                                \
-        StartupTimeToTimeTicks(begin_time).ToInternalValue(), "Temperature",  \
+        StartupTimeToTimeTicks(begin_time).ToInternalValue(), "Temperature",   \
         g_startup_temperature);                                                \
     TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP1(                                     \
         "startup", basename, 0,                                                \
-        StartupTimeToTimeTicks(end_time).ToInternalValue(), "Temperature",    \
+        StartupTimeToTimeTicks(end_time).ToInternalValue(), "Temperature",     \
         g_startup_temperature);                                                \
   }
 
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.h b/components/startup_metric_utils/startup_metric_utils.h
similarity index 95%
rename from components/startup_metric_utils/browser/startup_metric_utils.h
rename to components/startup_metric_utils/startup_metric_utils.h
index b071321..684046c 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.h
+++ b/components/startup_metric_utils/startup_metric_utils.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_UTILS_H_
-#define COMPONENTS_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_UTILS_H_
+#ifndef COMPONENTS_STARTUP_METRIC_UTILS_STARTUP_METRIC_UTILS_H_
+#define COMPONENTS_STARTUP_METRIC_UTILS_STARTUP_METRIC_UTILS_H_
 
 #include <string>
 
@@ -104,4 +104,4 @@
 
 }  // namespace startup_metric_utils
 
-#endif  // COMPONENTS_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_UTILS_H_
+#endif  // COMPONENTS_STARTUP_METRIC_UTILS_STARTUP_METRIC_UTILS_H_
diff --git a/components/strings/components_strings_am.xtb b/components/strings/components_strings_am.xtb
index 2c7ebce1..e80f586 100644
--- a/components/strings/components_strings_am.xtb
+++ b/components/strings/components_strings_am.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">የመጠባበቂያ ማከማቻ በመጥፎ ሁኔታ ላይ</translation>
 <translation id="5031870354684148875">ስለ Google ትርጉም</translation>
 <translation id="5045550434625856497">ትክክል ያልሆነ የይለፍ ቃል</translation>
+<translation id="5065199687811594072">Chromium የድር ቅጾችን ለማጠናቅቅ ይህን የክሬዲት ካርድ መረጃ እንዲያስቀምጥ ይፈልጋሉ?</translation>
 <translation id="5087286274860437796">የአገልጋይ የዕውቅና ማረጋገጫ በዚህ ጊዜ ላይ የሚሰራ አይደለም።</translation>
 <translation id="5089810972385038852">ግዛት</translation>
 <translation id="5094747076828555589">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በChromium የሚታመን አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb
index cd66366..90d1034 100644
--- a/components/strings/components_strings_ar.xtb
+++ b/components/strings/components_strings_ar.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">التخزين المساعد في حالة سيئة</translation>
 <translation id="5031870354684148875">‏معلومات عن الترجمة من Google</translation>
 <translation id="5045550434625856497">كلمة مرور غير صحيحة</translation>
+<translation id="5065199687811594072">‏هل تريد من Chromium حفظ معلومات بطاقة الائتمان لإكمال نماذج الويب؟</translation>
 <translation id="5087286274860437796">شهادة الخادم ليست صالحة حاليًا.</translation>
 <translation id="5089810972385038852">بلد/دولة</translation>
 <translation id="5094747076828555589">‏هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان غير موثوقة من قبل Chromium. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض الاتصال.</translation>
diff --git a/components/strings/components_strings_bg.xtb b/components/strings/components_strings_bg.xtb
index 333dfa50..0b19216 100644
--- a/components/strings/components_strings_bg.xtb
+++ b/components/strings/components_strings_bg.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Допълнителното хранилище е в лошо състояние</translation>
 <translation id="5031870354684148875">Всичко за Google Преводач</translation>
 <translation id="5045550434625856497">Неправилна парола</translation>
+<translation id="5065199687811594072">Искате ли Chromium да запази тази информация за кредитната карта за попълване на уеб формуляри?</translation>
 <translation id="5087286274860437796">Понастоящем сертификатът на сървъра не е валиден.</translation>
 <translation id="5089810972385038852">Щат</translation>
 <translation id="5094747076828555589">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; Chromium няма доверие на сертификата му за сигурност. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
diff --git a/components/strings/components_strings_bn.xtb b/components/strings/components_strings_bn.xtb
index 380e2d9..cb0d436 100644
--- a/components/strings/components_strings_bn.xtb
+++ b/components/strings/components_strings_bn.xtb
@@ -180,6 +180,7 @@
 <translation id="5019198164206649151">ব্যাকিং স্টোরটি ত্রুটিপূর্ণ অবস্থায় আছে</translation>
 <translation id="5031870354684148875">Google অনুবাদ সম্বন্ধে</translation>
 <translation id="5045550434625856497">ভুল পাসওয়ার্ড</translation>
+<translation id="5065199687811594072">আপনি কি চান যে ওয়েব ফর্ম পূরণ করার জন্য  Chromium এই ক্রেডিট কার্ড তথ্য পূরণ করুক?</translation>
 <translation id="5087286274860437796">সার্ভারের শংসাপত্র এই সময়ে বৈধ নয়৷</translation>
 <translation id="5089810972385038852">রাজ্য</translation>
 <translation id="5094747076828555589">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা শংসাপত্রটি Chromium এর নিকট বিশ্বাসযোগ্য নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
diff --git a/components/strings/components_strings_ca.xtb b/components/strings/components_strings_ca.xtb
index fc7b6911..6fbfa8a 100644
--- a/components/strings/components_strings_ca.xtb
+++ b/components/strings/components_strings_ca.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">L'emmagatzematge de la còpia de seguretat està en mal estat</translation>
 <translation id="5031870354684148875">Sobre el Traductor de Google</translation>
 <translation id="5045550434625856497">Contrasenya incorrecta</translation>
+<translation id="5065199687811594072">Voleu que Chromium desi la informació d'aquesta targeta de crèdit per completar formularis web?</translation>
 <translation id="5087286274860437796">En aquest moment el certificat del servidor no és vàlid.</translation>
 <translation id="5089810972385038852">Estat</translation>
 <translation id="5094747076828555589">Aquest servidor no ha pogut comprovar que sigui <ph name="DOMAIN" /> perquè Chromium considera que el seu certificat de seguretat no és de confiança. Això pot ser a causa d'una configuració incorrecta o d'un atacant que intercepta la vostra connexió.</translation>
diff --git a/components/strings/components_strings_cs.xtb b/components/strings/components_strings_cs.xtb
index 8b6421e..c2cd75c8 100644
--- a/components/strings/components_strings_cs.xtb
+++ b/components/strings/components_strings_cs.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Záložní úložiště je ve špatném stavu</translation>
 <translation id="5031870354684148875">O Překladači Google</translation>
 <translation id="5045550434625856497">Nesprávné heslo</translation>
+<translation id="5065199687811594072">Chcete v aplikaci Chromium uložit informace o této platební kartě k vyplňování formulářů?</translation>
 <translation id="5087286274860437796">Certifikát serveru v tuto chvíli není platný.</translation>
 <translation id="5089810972385038852">Stát/kraj</translation>
 <translation id="5094747076828555589">Server nedokázal prokázat, že patří doméně <ph name="DOMAIN" />. Chromium jeho bezpečnostnímu certifikátu nedůvěřuje. Může to být způsobeno nesprávnou konfigurací nebo tím, že vaše připojení zachytává útočník.</translation>
diff --git a/components/strings/components_strings_da.xtb b/components/strings/components_strings_da.xtb
index 3cdb3316..b750192c 100644
--- a/components/strings/components_strings_da.xtb
+++ b/components/strings/components_strings_da.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Sikkerhedskopien er fejlbehæftet</translation>
 <translation id="5031870354684148875">Om Google Oversæt</translation>
 <translation id="5045550434625856497">Ugyldig adgangskode</translation>
+<translation id="5065199687811594072">Er du sikker på, at Chromium skal gemme disse kreditkortoplysninger til udfyldning af webformularer?</translation>
 <translation id="5087286274860437796">Serverens certifikatet er ikke gyldigt i øjeblikket.</translation>
 <translation id="5089810972385038852">Delstat</translation>
 <translation id="5094747076828555589">Denne server kunne ikke bevise, at den er <ph name="DOMAIN" />, da Chromium ikke har tillid til sikkerhedscertifikatet. Dette kan skyldes en fejlkonfiguration, eller at en hacker har opfanget din forbindelse.</translation>
diff --git a/components/strings/components_strings_de.xtb b/components/strings/components_strings_de.xtb
index 24fef8a3..b995b57 100644
--- a/components/strings/components_strings_de.xtb
+++ b/components/strings/components_strings_de.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Sicherungsspeicher ist fehlerhaft.</translation>
 <translation id="5031870354684148875">Über Google Übersetzer</translation>
 <translation id="5045550434625856497">Falsches Passwort</translation>
+<translation id="5065199687811594072">Soll Chromium diese Kreditkartendaten zum Ausfüllen von Webformularen speichern?</translation>
 <translation id="5087286274860437796">Das Serverzertifikat ist zurzeit ungültig.</translation>
 <translation id="5089810972385038852">Bundesstaat/-land</translation>
 <translation id="5094747076828555589">Dieser Server konnte nicht beweisen, dass er <ph name="DOMAIN" /> ist. Sein Sicherheitszertifikat wird von Chromium als nicht vertrauenswürdig eingestuft. Mögliche Gründe sind eine fehlerhafte Konfiguration oder ein Angreifer, der Ihre Verbindung abfängt.</translation>
diff --git a/components/strings/components_strings_el.xtb b/components/strings/components_strings_el.xtb
index fb4960d1..f910e68 100644
--- a/components/strings/components_strings_el.xtb
+++ b/components/strings/components_strings_el.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Η αποθήκευση αντιγράφων ασφαλείας είναι σε κακή κατάσταση</translation>
 <translation id="5031870354684148875">Σχετικά με τη Google Μετάφραση</translation>
 <translation id="5045550434625856497">Λανθασμένος κωδικός πρόσβασης</translation>
+<translation id="5065199687811594072">Θέλετε το Chromium να αποθηκεύσει τις πληροφορίες αυτής της πιστωτικής κάρτας για τη συμπλήρωση φορμών ιστού;</translation>
 <translation id="5087286274860437796">Το πιστοποιητικό του διακομιστή δεν είναι έγκυρο αυτήν τη στιγμή.</translation>
 <translation id="5089810972385038852">Πολιτεία</translation>
 <translation id="5094747076828555589">Ο διακομιστής δεν μπορεί να αποδείξει ότι είναι το <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωρείται έμπιστο από το Chromium. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
diff --git a/components/strings/components_strings_en-GB.xtb b/components/strings/components_strings_en-GB.xtb
index e14bdeb..e52b8063 100644
--- a/components/strings/components_strings_en-GB.xtb
+++ b/components/strings/components_strings_en-GB.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Backing store in bad state</translation>
 <translation id="5031870354684148875">About Google Translate</translation>
 <translation id="5045550434625856497">Incorrect password</translation>
+<translation id="5065199687811594072">Do you want Chromium to save this credit card information for completing web forms?</translation>
 <translation id="5087286274860437796">Server's certificate is not valid at this time.</translation>
 <translation id="5089810972385038852">County</translation>
 <translation id="5094747076828555589">This server could not prove that it is <ph name="DOMAIN" />; its security certificate is not trusted by Chromium. This may be caused by a misconfiguration or an attacker intercepting your connection.</translation>
diff --git a/components/strings/components_strings_es-419.xtb b/components/strings/components_strings_es-419.xtb
index 547e53a..95c2df1 100644
--- a/components/strings/components_strings_es-419.xtb
+++ b/components/strings/components_strings_es-419.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">La memoria auxiliar se encuentra en mal estado.</translation>
 <translation id="5031870354684148875">Acerca de Google Traductor</translation>
 <translation id="5045550434625856497">Contraseña incorrecta</translation>
+<translation id="5065199687811594072">¿Quieres que Chromium guarde la información de esta tarjeta de crédito para completar formularios web?</translation>
 <translation id="5087286274860437796">El certificado del servidor no es válido en este momento.</translation>
 <translation id="5089810972385038852">Estado</translation>
 <translation id="5094747076828555589">Este servidor no pudo probar que su dominio es <ph name="DOMAIN" />; Chromium no confía en el certificado de seguridad. Es posible que esto se deba a una configuración incorrecta o a que un atacante interceptó la conexión.</translation>
diff --git a/components/strings/components_strings_es.xtb b/components/strings/components_strings_es.xtb
index 7c8aa5cf..0e3a96f 100644
--- a/components/strings/components_strings_es.xtb
+++ b/components/strings/components_strings_es.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">El almacén secundario está en mal estado.</translation>
 <translation id="5031870354684148875">Informacion del Traductor de Google</translation>
 <translation id="5045550434625856497">Contraseña incorrecta</translation>
+<translation id="5065199687811594072">¿Quieres que Chromium guarde la información de esta tarjeta de crédito para completar formularios web?</translation>
 <translation id="5087286274860437796">El certificado del servidor no es válido en este momento.</translation>
 <translation id="5089810972385038852">Estado</translation>
 <translation id="5094747076828555589">Este servidor no ha podido probar que su dominio es <ph name="DOMAIN" />, Chromium no confía en su certificado de seguridad. Este problema puede deberse a una configuración incorrecta o a que un atacante haya interceptado la conexión.</translation>
diff --git a/components/strings/components_strings_et.xtb b/components/strings/components_strings_et.xtb
index 64ab1c0..3540b5bb 100644
--- a/components/strings/components_strings_et.xtb
+++ b/components/strings/components_strings_et.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Varusalves esineb probleeme</translation>
 <translation id="5031870354684148875">Teave Google'i tõlke kohta</translation>
 <translation id="5045550434625856497">Vale parool</translation>
+<translation id="5065199687811594072">Kas soovite, et Chromium salvestaks krediitkaarditeabe veebivormide täitmiseks?</translation>
 <translation id="5087286274860437796">Serveri sertifikaat pole praegu kehtiv.</translation>
 <translation id="5089810972385038852">Osariik</translation>
 <translation id="5094747076828555589">Server ei suutnud tõestada, et see on domeen <ph name="DOMAIN" />, Chromium ei usalda selle turvasertifikaati. Selle põhjuseks võib olla vale seadistus või ründaja, kes on sekkunud teie ühendusse.</translation>
diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb
index 5755c8d1..ad79985 100644
--- a/components/strings/components_strings_fa.xtb
+++ b/components/strings/components_strings_fa.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">پشتیبان‌گیری ذخیره در وضعیت نادرست است</translation>
 <translation id="5031870354684148875">‏درباره Google Translate</translation>
 <translation id="5045550434625856497">گذرواژه نامعتبر</translation>
+<translation id="5065199687811594072">‏آیا می‌خواهید Chromium اطلاعات این کارت اعتباری را برای تکمیل فرم‌های وب ذخیره کند؟</translation>
 <translation id="5087286274860437796">در حال حاضر گواهی سرور معتبر نیست.</translation>
 <translation id="5089810972385038852">ایالت</translation>
 <translation id="5094747076828555589">‏این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیت آن مورد اعتماد Chromium نیست. علت این موضوع می‌توان پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
diff --git a/components/strings/components_strings_fi.xtb b/components/strings/components_strings_fi.xtb
index 36566a6d4..3135f83 100644
--- a/components/strings/components_strings_fi.xtb
+++ b/components/strings/components_strings_fi.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Tallennustila on virheellisessä tilassa</translation>
 <translation id="5031870354684148875">Tietoja Google-kääntäjästä</translation>
 <translation id="5045550434625856497">Väärä salasana</translation>
+<translation id="5065199687811594072">Haluatko Chromiumin tallentavan nämä luottokortin tiedot verkkolomakkeiden täydentämistä varten?</translation>
 <translation id="5087286274860437796">Palvelimen varmenne ei ole tällä hetkellä kelvollinen.</translation>
 <translation id="5089810972385038852">Osavaltio/alue</translation>
 <translation id="5094747076828555589">Palvelin ei voinut todistaa olevansa <ph name="DOMAIN" />; Chromium ei luota sen suojausvarmenteeseen. Tämä voi johtua määritysvirheestä tai verkkoyhteytesi siepanneesta hyökkääjästä.</translation>
diff --git a/components/strings/components_strings_fil.xtb b/components/strings/components_strings_fil.xtb
index 0f92ae5..9b1046e 100644
--- a/components/strings/components_strings_fil.xtb
+++ b/components/strings/components_strings_fil.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Hindi maganda ang katayuan ng backing store</translation>
 <translation id="5031870354684148875">Tungkol sa Google Translate</translation>
 <translation id="5045550434625856497">Hindi wastong password</translation>
+<translation id="5065199687811594072">Gusto mo bang i-save ng Chromium ang impormasyon ng credit card na ito para sa pagkumpleto ng mga form sa web?</translation>
 <translation id="5087286274860437796">Hindi angkop ang certificate ng server sa oras na ito.</translation>
 <translation id="5089810972385038852">Estado</translation>
 <translation id="5094747076828555589">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng Chromium ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation>
diff --git a/components/strings/components_strings_fr.xtb b/components/strings/components_strings_fr.xtb
index fe5e9e0..fbe23dc 100644
--- a/components/strings/components_strings_fr.xtb
+++ b/components/strings/components_strings_fr.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">L'espace de stockage destiné à la sauvegarde est en mauvais état.</translation>
 <translation id="5031870354684148875">À propos de Google Traduction</translation>
 <translation id="5045550434625856497">Mot de passe incorrect.</translation>
+<translation id="5065199687811594072">Voulez-vous que les informations de carte de paiement soient enregistrées dans Chromium pour le remplissage de formulaires Web ?</translation>
 <translation id="5087286274860437796">Le certificat actuel du serveur n'est pas valide.</translation>
 <translation id="5089810972385038852">État</translation>
 <translation id="5094747076828555589">Impossible de vérifier sur le serveur qu'il s'agit bien du domaine <ph name="DOMAIN" />, car son certificat de sécurité n'est pas considéré comme fiable par Chromium. Cela peut être dû à une mauvaise configuration ou bien à l'interception de votre connexion par un pirate informatique.</translation>
diff --git a/components/strings/components_strings_gu.xtb b/components/strings/components_strings_gu.xtb
index be95c8c..c6bf39fe 100644
--- a/components/strings/components_strings_gu.xtb
+++ b/components/strings/components_strings_gu.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">બેકઅપ સ્ટોર કરવું ખરાબ સ્થિતિમાં છે</translation>
 <translation id="5031870354684148875">Google અનુવાદ વિશે</translation>
 <translation id="5045550434625856497">ખોટો પાસવર્ડ</translation>
+<translation id="5065199687811594072">શું તમે ઇચ્છો છો કે વેબ ફોર્મ્સ પૂર્ણ કરવા માટે આ ક્રેડિટ કાર્ડ માહિતી Chromium સાચવી રાખે?</translation>
 <translation id="5087286274860437796">સર્વરનું પ્રમાણપત્ર આ સમયે માન્ય નથી.</translation>
 <translation id="5089810972385038852">રાજ્ય</translation>
 <translation id="5094747076828555589">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર Chromium દ્વારા વિશ્વસનીય નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
diff --git a/components/strings/components_strings_hi.xtb b/components/strings/components_strings_hi.xtb
index 20bd2f22..06f4314 100644
--- a/components/strings/components_strings_hi.xtb
+++ b/components/strings/components_strings_hi.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">बैकिंग संग्रह खराब स्थिति में है</translation>
 <translation id="5031870354684148875">Google अनुवाद के बारे में</translation>
 <translation id="5045550434625856497">गलत पासवर्ड</translation>
+<translation id="5065199687811594072">क्या आप चाहते हैं कि वेब फ़ॉर्म पूरा करने के लिए क्रोमियम इस क्रेडिट कार्ड जानकारी को सहेजे?</translation>
 <translation id="5087286274860437796">सर्वर का प्रमाण पत्र इस समय मान्य नहीं है.</translation>
 <translation id="5089810972385038852">राज्य</translation>
 <translation id="5094747076828555589">यह सर्वर यह नहीं प्रमाणित कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र Chromium द्वारा विश्वसनीय नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
diff --git a/components/strings/components_strings_hr.xtb b/components/strings/components_strings_hr.xtb
index 144a4bd..e7fd4ef 100644
--- a/components/strings/components_strings_hr.xtb
+++ b/components/strings/components_strings_hr.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Sigurnosno pohranjivanje u neispravnom je stanju</translation>
 <translation id="5031870354684148875">O Google Prevoditelju</translation>
 <translation id="5045550434625856497">Netočna zaporka</translation>
+<translation id="5065199687811594072">Želite li da Chromium spremi podatke o toj kreditnoj kartici za dovršavanje web-obrazaca?</translation>
 <translation id="5087286274860437796">Certifikat poslužitelja trenutačno nije važeći.</translation>
 <translation id="5089810972385038852">Država</translation>
 <translation id="5094747076828555589">Poslužitelj nije mogao dokazati da je <ph name="DOMAIN" />; Chromium smatra da njegov sigurnosni certifikat nije pouzdan. To može biti uzrokovano pogrešnom konfiguracijom ili napadom na vašu vezu.</translation>
diff --git a/components/strings/components_strings_hu.xtb b/components/strings/components_strings_hu.xtb
index f153841..6db8d487 100644
--- a/components/strings/components_strings_hu.xtb
+++ b/components/strings/components_strings_hu.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">A háttértároló állapota nem megfelelő</translation>
 <translation id="5031870354684148875">A Google Fordító leírása</translation>
 <translation id="5045550434625856497">Téves jelszó</translation>
+<translation id="5065199687811594072">Szeretné, hogy a Chromium mentse ezt a bankkártya-információt az internetes űrlapok kitöltéséhez?</translation>
 <translation id="5087286274860437796">A szerver tanúsítványa jelenleg nem érvényes.</translation>
 <translation id="5089810972385038852">Állam</translation>
 <translation id="5094747076828555589">A szerver nem tudta bizonyítani, hogy valóban a(z) <ph name="DOMAIN" /> domainbe tartozik; biztonsági tanúsítványa a Chromium szerint nem megbízható. Ennek oka lehet konfigurációs hiba, vagy hogy egy támadó eltérítette az Ön kapcsolódását.</translation>
diff --git a/components/strings/components_strings_id.xtb b/components/strings/components_strings_id.xtb
index 69a6439d..5f9ea7b7 100644
--- a/components/strings/components_strings_id.xtb
+++ b/components/strings/components_strings_id.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Penyimpanan cadangan dalam kondisi buruk</translation>
 <translation id="5031870354684148875">Tentang Google Terjemahan</translation>
 <translation id="5045550434625856497">Sandi salah</translation>
+<translation id="5065199687811594072">Ingin Chrome menyimpan informasi kartu kredit ini untuk melengkapi formulir web?</translation>
 <translation id="5087286274860437796">Sertifikat server saat ini tidak valid.</translation>
 <translation id="5089810972385038852">Negara bagian</translation>
 <translation id="5094747076828555589">Server ini tidak dapat membuktikan bahwa ini adalah <ph name="DOMAIN" />; sertifikat keamanannya tidak dipercaya oleh Chromium. Hal ini dapat disebabkan oleh kesalahan konfigurasi atau penyerang memotong sambungan Anda.</translation>
diff --git a/components/strings/components_strings_it.xtb b/components/strings/components_strings_it.xtb
index b20bc5f3..62cea7ed 100644
--- a/components/strings/components_strings_it.xtb
+++ b/components/strings/components_strings_it.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Archivio di backup in stato non valido</translation>
 <translation id="5031870354684148875">Informazioni su Google Traduttore</translation>
 <translation id="5045550434625856497">Password non corretta</translation>
+<translation id="5065199687811594072">Desideri che Chromium salvi i dati della carta di credito per la compilazione dei moduli web?</translation>
 <translation id="5087286274860437796">Il certificato del server non è valido in questa fase.</translation>
 <translation id="5089810972385038852">Provincia</translation>
 <translation id="5094747076828555589">Questo server non è riuscito a dimostrare che si tratta di <ph name="DOMAIN" />; il relativo certificato di sicurezza non è considerato attendibile da Chromium. Il problema potrebbe essere dovuto a un'errata configurazione o a un malintenzionato che intercetta la connessione.</translation>
diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb
index c21269e..f014da2 100644
--- a/components/strings/components_strings_iw.xtb
+++ b/components/strings/components_strings_iw.xtb
@@ -183,6 +183,7 @@
 <translation id="5019198164206649151">האחסון המשמש כגיבוי אינו תקין</translation>
 <translation id="5031870354684148875">‏מידע על Google Translate</translation>
 <translation id="5045550434625856497">סיסמה שגויה</translation>
+<translation id="5065199687811594072">‏האם ברצונך ש-Chromium ישמור פרטים אלה של כרטיס האשראי להשלמת טופסי אינטרנט?</translation>
 <translation id="5087286274860437796">האישור של השרת אינו תקף כעת.</translation>
 <translation id="5089810972385038852">מדינה</translation>
 <translation id="5094747076828555589">‏השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו לא נחשב כמהימן על ידי Chromium. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
diff --git a/components/strings/components_strings_ja.xtb b/components/strings/components_strings_ja.xtb
index 311edb2c..a800ed7 100644
--- a/components/strings/components_strings_ja.xtb
+++ b/components/strings/components_strings_ja.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">代替ストアの状態が不適切です</translation>
 <translation id="5031870354684148875">Google 翻訳について</translation>
 <translation id="5045550434625856497">パスワードが正しくありません</translation>
+<translation id="5065199687811594072">このクレジット カード情報を Chromium に保存してウェブ フォームの自動入力に使用しますか?</translation>
 <translation id="5087286274860437796">サーバーの証明書が現在有効ではありません。</translation>
 <translation id="5089810972385038852">都道府県 / 州</translation>
 <translation id="5094747076828555589">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は Chromium によって信頼されているものではありません。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
diff --git a/components/strings/components_strings_kn.xtb b/components/strings/components_strings_kn.xtb
index 7dbad3e..46707241 100644
--- a/components/strings/components_strings_kn.xtb
+++ b/components/strings/components_strings_kn.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">ಕಳಪೆ ಸ್ಥಿತಿಯಲ್ಲಿ ಸಂಗ್ರಹಣೆಯನ್ನು ಹಿಂತಿರುಗಿಸಲಾಗಿದೆ</translation>
 <translation id="5031870354684148875">Google ಅನುವಾದದ ಕುರಿತು</translation>
 <translation id="5045550434625856497">ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್</translation>
+<translation id="5065199687811594072">ವೆಬ್ ಫಾರ್ಮ್‌ಗಳನ್ನು ಪೂರೈಸುವುದಕ್ಕಾಗಿ ಈ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಮಾಹಿತಿಯನ್ನು ಉಳಿಸಲು ನಿಮಗೆ Chromium ಬೇಕಾಗಿದೆಯೇ?</translation>
 <translation id="5087286274860437796">ಈ ಸಮಯದಲ್ಲಿ ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರ ಮಾನ್ಯವಾಗಿಲ್ಲ.</translation>
 <translation id="5089810972385038852">ರಾಜ್ಯ</translation>
 <translation id="5094747076828555589">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು Chromium ಮೂಲಕ ವಿಶ್ವಾಸಾರ್ಹವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb
index 8692b3a..f0e2163 100644
--- a/components/strings/components_strings_ko.xtb
+++ b/components/strings/components_strings_ko.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">보조 기억 장치 상태가 잘못됨</translation>
 <translation id="5031870354684148875">Google 번역 정보</translation>
 <translation id="5045550434625856497">비밀번호가 잘못되었습니다.</translation>
+<translation id="5065199687811594072">웹 양식을 작성하기 위해 Chromium에서 신용카드 정보를 저장해도 되겠습니까?</translation>
 <translation id="5087286274860437796">서버의 인증서가 현재 유효하지 않습니다.</translation>
 <translation id="5089810972385038852">주</translation>
 <translation id="5094747076828555589">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 Chromium에서 신뢰하는 보안 인증서가 아닙니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
diff --git a/components/strings/components_strings_lt.xtb b/components/strings/components_strings_lt.xtb
index a8a46f6..51e10b8 100644
--- a/components/strings/components_strings_lt.xtb
+++ b/components/strings/components_strings_lt.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Bloga atsarginio atminties įrenginio būsena</translation>
 <translation id="5031870354684148875">Apie „Google“ vertėją</translation>
 <translation id="5045550434625856497">Netinkamas slaptažodis</translation>
+<translation id="5065199687811594072">Ar norite, kad „Chromium“ išsaugotų šią kredito kortelės informaciją ir naudotų ją žiniatinklio formoms užpildyti?</translation>
 <translation id="5087286274860437796">Šiuo metu serverio sertifikatas negalioja.</translation>
 <translation id="5089810972385038852">Valstija</translation>
 <translation id="5094747076828555589">Šiam serveriui nepavyko patvirtinti, kad tai yra <ph name="DOMAIN" />; jo saugos sertifikatas nėra patikimas „Chromium“. Taip gali nutikti dėl netinkamos konfigūracijos ar dėl ryšį pertraukusio užgrobėjo.</translation>
diff --git a/components/strings/components_strings_lv.xtb b/components/strings/components_strings_lv.xtb
index 814a395..117af9f7 100644
--- a/components/strings/components_strings_lv.xtb
+++ b/components/strings/components_strings_lv.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Dublējumu krātuve nav labā stāvoklī.</translation>
 <translation id="5031870354684148875">Par Google tulkotāju</translation>
 <translation id="5045550434625856497">Nepareiza parole</translation>
+<translation id="5065199687811594072">Vai vēlaties, lai Chromium saglabātu šo kredītkartes informāciju tīmekļa veidlapu aizpildīšanai?</translation>
 <translation id="5087286274860437796">Servera sertifikāts šobrīd nav derīgs.</translation>
 <translation id="5089810972385038852">Štats</translation>
 <translation id="5094747076828555589">Šis serveris nevarēja pierādīt, ka šī ir vietne <ph name="DOMAIN" />; tās drošības sertifikāts netiek uzskatīts par uzticamu Chromium sistēmā. Iespējams, tas ir nepareizas konfigurācijas dēļ vai arī kāds ir ļaunprātīgi izmantojis jūsu savienojumu.</translation>
diff --git a/components/strings/components_strings_ml.xtb b/components/strings/components_strings_ml.xtb
index 69b2e4b..5882b52 100644
--- a/components/strings/components_strings_ml.xtb
+++ b/components/strings/components_strings_ml.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">ബാക്കിംഗ് സംഭരണം മോശം അവസ്ഥയിലാണ്</translation>
 <translation id="5031870354684148875">Google വിവര്‍ത്തനം എന്നതിനെക്കുറിച്ച് </translation>
 <translation id="5045550434625856497">പാസ്‌വേഡ് തെറ്റാണ്</translation>
+<translation id="5065199687811594072">വെബ് ഫോമുകള്‍‌ പൂര്‍‌ത്തിയാക്കുന്നതിനായി ഈ ക്രെഡിറ്റ് കാര്‍‌ഡ് വിവരങ്ങള്‍‌ Chromium സംരക്ഷിക്കേണ്ടതുണ്ടോ?</translation>
 <translation id="5087286274860437796">സെർവറിന്റെ സർട്ടിഫിക്കറ്റിന് ഇപ്പോൾ സാധുതയില്ല.</translation>
 <translation id="5089810972385038852">സ്റ്റേറ്റ്</translation>
 <translation id="5094747076828555589">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റിനെ Chromium-ത്തിന്ന് പരിചയമില്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
diff --git a/components/strings/components_strings_mr.xtb b/components/strings/components_strings_mr.xtb
index 17c9a9ad..f94034d 100644
--- a/components/strings/components_strings_mr.xtb
+++ b/components/strings/components_strings_mr.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">समर्थन संचयन खराब स्थितीत</translation>
 <translation id="5031870354684148875">Google अनुवाद बद्दल</translation>
 <translation id="5045550434625856497">अयोग्य संकेतशब्द</translation>
+<translation id="5065199687811594072">वेब फॉर्म पूर्ण करण्याकरिता ही क्रेडिट कार्ड माहिती Chromium ने जतन करावी असे आपण इच्छिता?</translation>
 <translation id="5087286274860437796">यावेळी सर्व्हरचे प्रमाणपत्र वैध नाही.</translation>
 <translation id="5089810972385038852">राज्य</translation>
 <translation id="5094747076828555589">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता प्रमाणपत्र Chromium द्वारे विश्वसनीय नाही. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा आक्रमणकर्त्याने आपले कनेक्शन आंतरखंडित केल्यामुळे झाले असू शकते.</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb
index ddf360cb1..ba088622 100644
--- a/components/strings/components_strings_ms.xtb
+++ b/components/strings/components_strings_ms.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Simpanan penyandaran dalam keadaan buruk</translation>
 <translation id="5031870354684148875">Perihal Google Terjemah</translation>
 <translation id="5045550434625856497">Kata laluan tidak sah</translation>
+<translation id="5065199687811594072">Adakah anda mahu Chromium menyimpan maklumat kad kredit ini untuk melengkapkan borang web?</translation>
 <translation id="5087286274860437796">Sijil pelayan tidak sah pada masa ini.</translation>
 <translation id="5089810972385038852">Negeri</translation>
 <translation id="5094747076828555589">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh Chromium. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation>
diff --git a/components/strings/components_strings_nl.xtb b/components/strings/components_strings_nl.xtb
index 96043460..b8734c3 100644
--- a/components/strings/components_strings_nl.xtb
+++ b/components/strings/components_strings_nl.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Backend-opslag in slechte staat</translation>
 <translation id="5031870354684148875">Over Google Translate</translation>
 <translation id="5045550434625856497">Onjuist wachtwoord</translation>
+<translation id="5065199687811594072">Wil je dat Chromium deze creditcardgegevens opslaat voor het invullen van webformulieren?</translation>
 <translation id="5087286274860437796">Het servercertificaat is momenteel niet geldig.</translation>
 <translation id="5089810972385038852">Staat</translation>
 <translation id="5094747076828555589">De server kan niet bewijzen dat dit <ph name="DOMAIN" /> is. Het beveiligingscertificaat van de server wordt niet vertrouwd door Chromium. Dit kan worden veroorzaakt door een verkeerde configuratie of een aanvaller die je verbinding onderschept.</translation>
diff --git a/components/strings/components_strings_no.xtb b/components/strings/components_strings_no.xtb
index 7c3d8ef8..57c9ee2 100644
--- a/components/strings/components_strings_no.xtb
+++ b/components/strings/components_strings_no.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Ugyldig funksjonalitet for sikkerhetskopiering</translation>
 <translation id="5031870354684148875">Om Google Oversett</translation>
 <translation id="5045550434625856497">Feil passord</translation>
+<translation id="5065199687811594072">Vil du at Chromium skal lagre denne kredittkortinformasjonen for utfylling av nettskjemaer?</translation>
 <translation id="5087286274860437796">Sertifikatet til tjeneren er ikke gyldig for øyeblikket.</translation>
 <translation id="5089810972385038852">Fylke / delstat</translation>
 <translation id="5094747076828555589">Denne tjeneren kunne ikke bevise at den er <ph name="DOMAIN" />. Sikkerhetssertifikatet til tjeneren er ikke klarert av Chromium. Dette kan være forårsaket av en feilkonfigurering eller en angriper som avskjærer tilkoblingen din.</translation>
@@ -269,7 +270,7 @@
 <translation id="7298195798382681320">Anbefalt</translation>
 <translation id="7334320624316649418">&amp;Omorganiser likevel</translation>
 <translation id="7353601530677266744">Kommandolinje </translation>
-<translation id="7378627244592794276">Nei takk</translation>
+<translation id="7378627244592794276">Nei, takk</translation>
 <translation id="7400418766976504921">Nettadresse</translation>
 <translation id="7419106976560586862">Profilbane</translation>
 <translation id="7441627299479586546">Feil emne for innstillinger</translation>
@@ -288,7 +289,7 @@
 <translation id="7761701407923456692">Tjenerens sertifikat samsvarer ikke med nettadressen.</translation>
 <translation id="777702478322588152">Prefektur</translation>
 <translation id="7791543448312431591">Legg til</translation>
-<translation id="780301667611848630">Nei takk</translation>
+<translation id="780301667611848630">Nei, takk</translation>
 <translation id="7805768142964895445">Status</translation>
 <translation id="7813600968533626083">Vil du fjerne skjemaforslaget fra Chrome?</translation>
 <translation id="7887683347370398519">Kontrollér CVC-koden din, og prøv igjen.</translation>
diff --git a/components/strings/components_strings_pl.xtb b/components/strings/components_strings_pl.xtb
index d38fd21..a82cd12bd 100644
--- a/components/strings/components_strings_pl.xtb
+++ b/components/strings/components_strings_pl.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Nieprawidłowy stan magazynu wspomagającego</translation>
 <translation id="5031870354684148875">Tłumacz Google – informacje</translation>
 <translation id="5045550434625856497">Nieprawidłowe hasło</translation>
+<translation id="5065199687811594072">Czy Chromium ma zapisać informacje o karcie kredytowej, by ułatwić wypełnianie formularzy w przyszłości?</translation>
 <translation id="5087286274860437796">Certyfikat serwera nie jest obecnie ważny.</translation>
 <translation id="5089810972385038852">Stan</translation>
 <translation id="5094747076828555589">Ten serwer nie mógł udowodnić, że należy do <ph name="DOMAIN" />. Jego certyfikat bezpieczeństwa nie jest zaufany w Chromium. Może to być spowodowane błędną konfiguracją lub przechwyceniem połączenia przez atakującego.</translation>
diff --git a/components/strings/components_strings_pt-BR.xtb b/components/strings/components_strings_pt-BR.xtb
index 4b9dfdf23..84551ced 100644
--- a/components/strings/components_strings_pt-BR.xtb
+++ b/components/strings/components_strings_pt-BR.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Armazenamento de backup em estado inválido</translation>
 <translation id="5031870354684148875">Sobre o Google Tradutor</translation>
 <translation id="5045550434625856497">Senha incorreta</translation>
+<translation id="5065199687811594072">Deseja que o Chromium salve as informações deste cartão de crédito para preencher formulários da Web?</translation>
 <translation id="5087286274860437796">O certificado do servidor não é válido no momento.</translation>
 <translation id="5089810972385038852">Estado</translation>
 <translation id="5094747076828555589">Este servidor não conseguiu provar que é <ph name="DOMAIN" />. O certificado de segurança não é confiável para o Chromium. Isso pode ser causado por uma configuração incorreta ou pela interceptação da sua conexão por um invasor.</translation>
diff --git a/components/strings/components_strings_pt-PT.xtb b/components/strings/components_strings_pt-PT.xtb
index 527ae81..398b6b88 100644
--- a/components/strings/components_strings_pt-PT.xtb
+++ b/components/strings/components_strings_pt-PT.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Armazenamento de segurança em mau estado</translation>
 <translation id="5031870354684148875">Acerca do Google Tradutor</translation>
 <translation id="5045550434625856497">Palavra-passe incorreta</translation>
+<translation id="5065199687811594072">Pretende que o Chromium guarde estas informações de cartão de crédito para preenchimento de formulários Web?</translation>
 <translation id="5087286274860437796">De momento, o certificado do servidor não é válido.</translation>
 <translation id="5089810972385038852">Estado</translation>
 <translation id="5094747076828555589">Este servidor não conseguiu provar que é o domínio <ph name="DOMAIN" />; o Chromium não confia no respetivo certificado de segurança. Isto pode ser o resultado de uma configuração incorreta ou de um invasor a intercetar a sua ligação.</translation>
diff --git a/components/strings/components_strings_ro.xtb b/components/strings/components_strings_ro.xtb
index 370aa49d8..319eba8 100644
--- a/components/strings/components_strings_ro.xtb
+++ b/components/strings/components_strings_ro.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Depozit de fundal în stare nevalidă</translation>
 <translation id="5031870354684148875">Despre Google Traducere</translation>
 <translation id="5045550434625856497">Parolă incorectă</translation>
+<translation id="5065199687811594072">Doriți ca Chromium să salveze informațiile privind cardul de credit pentru completarea formularelor web?</translation>
 <translation id="5087286274860437796">Momentan, certificatul serverului este nevalid.</translation>
 <translation id="5089810972385038852">Stat</translation>
 <translation id="5094747076828555589">Acest server nu a putut dovedi că este <ph name="DOMAIN" />; Chromium nu consideră că certificatul său de securitate este de încredere. Cauza poate fi o configurare greșită sau interceptarea conexiunii de către un atacator.</translation>
diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb
index 401d493..9b41466 100644
--- a/components/strings/components_strings_ru.xtb
+++ b/components/strings/components_strings_ru.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Данные в хранилище повреждены</translation>
 <translation id="5031870354684148875">О Переводчике Google</translation>
 <translation id="5045550434625856497">Неправильный пароль</translation>
+<translation id="5065199687811594072">Сохранить в Chromium данные этой карты для заполнения веб-форм?</translation>
 <translation id="5087286274860437796">Сертификат сервера не действителен в настоящее время.</translation>
 <translation id="5089810972385038852">Штат</translation>
 <translation id="5094747076828555589">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Chromium не доверяет его сертификату безопасности. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
diff --git a/components/strings/components_strings_sk.xtb b/components/strings/components_strings_sk.xtb
index 175bec0b..4b8244c2 100644
--- a/components/strings/components_strings_sk.xtb
+++ b/components/strings/components_strings_sk.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Zlý stav záložného ukladacieho priestoru</translation>
 <translation id="5031870354684148875">O službe Prekladač Google</translation>
 <translation id="5045550434625856497">Nesprávne heslo</translation>
+<translation id="5065199687811594072">Má prehliadač Chromium uložiť informácie o tejto kreditnej karte a použiť ich pri vypĺňaní ďalších webových formulárov?</translation>
 <translation id="5087286274860437796">Certifikát servera je momentálne neplatný</translation>
 <translation id="5089810972385038852">Štát</translation>
 <translation id="5094747076828555589">Server nedokáže overiť, či ide o doménu <ph name="DOMAIN" />, Chromium nedôveruje jej bezpečnostnému certifikátu. Môže to byť spôsobené nesprávnou konfiguráciou alebo tým, že vaše pripojenie zachytil útočník.</translation>
diff --git a/components/strings/components_strings_sl.xtb b/components/strings/components_strings_sl.xtb
index f85af415..fedea25a 100644
--- a/components/strings/components_strings_sl.xtb
+++ b/components/strings/components_strings_sl.xtb
@@ -180,6 +180,7 @@
 <translation id="5019198164206649151">Neprimerno stanje rezervne shrambe</translation>
 <translation id="5031870354684148875">Google Prevajalnik – vizitka</translation>
 <translation id="5045550434625856497">Napačno geslo</translation>
+<translation id="5065199687811594072">Ali želite, da Chromium shrani podatke o tej kreditni kartici za izpolnjevanje spletnih obrazcev?</translation>
 <translation id="5087286274860437796">Potrdilo strežnika trenutno ni veljavno.</translation>
 <translation id="5089810972385038852">Zvezna država</translation>
 <translation id="5094747076828555589">Strežniku ni uspelo dokazati, da je <ph name="DOMAIN" />; Chromium ne zaupa njegovemu varnostnemu potrdilu. Razlog za to je lahko napačna konfiguracija ali napadalčevo prestrezanje povezave.</translation>
diff --git a/components/strings/components_strings_sr.xtb b/components/strings/components_strings_sr.xtb
index 27ecd56..29549e7 100644
--- a/components/strings/components_strings_sr.xtb
+++ b/components/strings/components_strings_sr.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Складиште тока података је у лошем стању</translation>
 <translation id="5031870354684148875">О Google преводиоцу</translation>
 <translation id="5045550434625856497">Нетачна лозинка</translation>
+<translation id="5065199687811594072">Желите ли да Chromium сачува ове информације о кредитној картици за попуњавање веб-образаца?</translation>
 <translation id="5087286274860437796">Сертификат сервера тренутно није важећи.</translation>
 <translation id="5089810972385038852">Држава</translation>
 <translation id="5094747076828555589">Овај сервер не може да докаже да је <ph name="DOMAIN" />; Chromium нема поверења у његов безбедносни сертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
diff --git a/components/strings/components_strings_sv.xtb b/components/strings/components_strings_sv.xtb
index 298c671..c0d0d92d 100644
--- a/components/strings/components_strings_sv.xtb
+++ b/components/strings/components_strings_sv.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Säkerhetskopian har dålig status</translation>
 <translation id="5031870354684148875">Om Google Översätt</translation>
 <translation id="5045550434625856497">Felaktigt lösenord</translation>
+<translation id="5065199687811594072">Vill du att Chromium ska spara kreditkortsuppgifterna vid automatisk ifyllning av webbformulär?</translation>
 <translation id="5087286274860437796">Servercertifikatet är inte giltigt för närvarande.</translation>
 <translation id="5089810972385038852">Delstat</translation>
 <translation id="5094747076828555589">Servern kunde inte bevisa att den är <ph name="DOMAIN" /> eftersom Chromium inte litar på dess säkerhetscertifikat. Detta kan orsakas av en felaktig konfigurering eller att någon spärrar anslutningen.</translation>
diff --git a/components/strings/components_strings_sw.xtb b/components/strings/components_strings_sw.xtb
index ab89613..a33858c 100644
--- a/components/strings/components_strings_sw.xtb
+++ b/components/strings/components_strings_sw.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Hifadhi la kucheleza liko katika hali mbaya</translation>
 <translation id="5031870354684148875">Kuhusu Google Tafsiri</translation>
 <translation id="5045550434625856497">Nenosiri lisilo sahihi</translation>
+<translation id="5065199687811594072">Je, unataka Chromium ihifadhi maelezo haya ya kadi ya mkopo ya kukamilisha fomu za wavuti?</translation>
 <translation id="5087286274860437796">Cheti cha seva si sahihi kwa sasa.</translation>
 <translation id="5089810972385038852">Jimbo</translation>
 <translation id="5094747076828555589">Seva hii haikuweza kuthibitisha kuwa ni <ph name="DOMAIN" />; cheti chake cha usalama hakiaminiwi na Chromium. Hii inaweza kusababishwa na kusanidi kusikofaa au mvamizi kuingilia muunganisho wako.</translation>
@@ -288,7 +289,7 @@
 <translation id="7761701407923456692">Cheti cha seva hakilingani na URL.</translation>
 <translation id="777702478322588152">Wilaya</translation>
 <translation id="7791543448312431591">Ongeza</translation>
-<translation id="780301667611848630">La, asante</translation>
+<translation id="780301667611848630">Sitaki</translation>
 <translation id="7805768142964895445">Hali</translation>
 <translation id="7813600968533626083">Ungependa kuondoa pendekezo la fomu kutoka kwenye Chrome?</translation>
 <translation id="7887683347370398519">Angalia CVC yako na ujaribu tena</translation>
diff --git a/components/strings/components_strings_ta.xtb b/components/strings/components_strings_ta.xtb
index 56a2f5c3..96d4973 100644
--- a/components/strings/components_strings_ta.xtb
+++ b/components/strings/components_strings_ta.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">தவறான நிலையில் மீட்பு சேமிப்பு உள்ளது</translation>
 <translation id="5031870354684148875">Google மொழியாக்கம் ஓர் அறிமுகம்</translation>
 <translation id="5045550434625856497">தவறான கடவுச்சொல்</translation>
+<translation id="5065199687811594072">வலைப் படிவங்களை நிறைவுசெய்வதற்காக, இந்தக் கிரெடிட் கார்டுத் தகவலை Chromium சேமிக்க வேண்டும் என்று நீங்கள் விரும்புகிறீர்களா?</translation>
 <translation id="5087286274860437796">தற்போது சேவையகத்தின் சான்றிதழ் செல்லுபடியாகாது.</translation>
 <translation id="5089810972385038852">மாநிலம்</translation>
 <translation id="5094747076828555589">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழை Chromium நம்பவில்லை. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
diff --git a/components/strings/components_strings_te.xtb b/components/strings/components_strings_te.xtb
index 32bde10..efd9445 100644
--- a/components/strings/components_strings_te.xtb
+++ b/components/strings/components_strings_te.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">బ్యాకింగ్ నిల్వ చెల్లని స్థితిలో ఉంది</translation>
 <translation id="5031870354684148875">Google అనువాదం గురించి</translation>
 <translation id="5045550434625856497">తప్పు పాస్‌వర్డ్</translation>
+<translation id="5065199687811594072">మీరు వెబ్ ఫారమ్‌లను పూర్తి చేయడానికి Chromium ఈ క్రెడిట్ కార్డ్ సమాచారాన్ని సేవ్ చేయాలని కోరుకుంటున్నారా?</translation>
 <translation id="5087286274860437796">ప్రస్తుతం సర్వర్ ప్రమాణపత్రం చెల్లదు.</translation>
 <translation id="5089810972385038852">రాష్ట్రం</translation>
 <translation id="5094747076828555589">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రాన్ని Chromium విశ్వసించలేదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కి అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
diff --git a/components/strings/components_strings_th.xtb b/components/strings/components_strings_th.xtb
index 954f681..874cfac 100644
--- a/components/strings/components_strings_th.xtb
+++ b/components/strings/components_strings_th.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">ไม่สามารถจัดเก็บเนื่องจากระบบแบ็คเอนด์อยู่ในสถานะไม่ดี</translation>
 <translation id="5031870354684148875">เกี่ยวกับ Google แปลภาษา</translation>
 <translation id="5045550434625856497">รหัสผ่านไม่ถูกต้อง</translation>
+<translation id="5065199687811594072">คุณต้องการให้ Chromium บันทึกข้อมูลบัตรเครดิตนี้เพื่อใช้กรอกแบบฟอร์มบนเว็บไหม</translation>
 <translation id="5087286274860437796">ใบรับรองของเซิร์ฟเวอร์ไม่สามารถใช้ได้ในขณะนี้</translation>
 <translation id="5089810972385038852">รัฐ</translation>
 <translation id="5094747076828555589">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะ Chromium ไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
diff --git a/components/strings/components_strings_tr.xtb b/components/strings/components_strings_tr.xtb
index ad34bd5..aaedbf44 100644
--- a/components/strings/components_strings_tr.xtb
+++ b/components/strings/components_strings_tr.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Yedekleme deposu kötü durumda</translation>
 <translation id="5031870354684148875">Google Çeviri Hakkında</translation>
 <translation id="5045550434625856497">Yanlış şifre</translation>
+<translation id="5065199687811594072">Chromium'un, web formlarını doldurmak için bu kredi kartı bilgilerini kaydetmesini ister misiniz?</translation>
 <translation id="5087286274860437796">Sunucu sertifikası şu anda geçerli değil.</translation>
 <translation id="5089810972385038852">Eyalet</translation>
 <translation id="5094747076828555589">Bu sunucu <ph name="DOMAIN" /> olduğunu kanıtlayamadı; Chromium, sunucunun güvenlik sertifikasına güvenmiyor. Bu durum, bir yanlış yapılandırmadan veya bağlantıya müdahale eden bir saldırgandan kaynaklanıyor olabilir.</translation>
diff --git a/components/strings/components_strings_uk.xtb b/components/strings/components_strings_uk.xtb
index ba763e60..f362201e 100644
--- a/components/strings/components_strings_uk.xtb
+++ b/components/strings/components_strings_uk.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Резервний носій пошкоджено</translation>
 <translation id="5031870354684148875">Про Перекладач Google</translation>
 <translation id="5045550434625856497">Неправильний пароль</translation>
+<translation id="5065199687811594072">Зберігати дані цієї кредитної картки в Chromium для заповнення веб-форм?</translation>
 <translation id="5087286274860437796">Сертифікат сервера зараз недійсний.</translation>
 <translation id="5089810972385038852">Штат</translation>
 <translation id="5094747076828555589">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Chromium не вважає його сертифікат безпеки надійним. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
diff --git a/components/strings/components_strings_vi.xtb b/components/strings/components_strings_vi.xtb
index f9a61b8..3772c72 100644
--- a/components/strings/components_strings_vi.xtb
+++ b/components/strings/components_strings_vi.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">Không thể lưu trữ do chương trình phụ trợ ở trạng thái xấu</translation>
 <translation id="5031870354684148875">Giới thiệu về Google Dịch</translation>
 <translation id="5045550434625856497">Mật khẩu sai</translation>
+<translation id="5065199687811594072">Bạn có muốn Chromium lưu thông tin thẻ tín dụng này để hoàn thành các biểu mẫu web không?</translation>
 <translation id="5087286274860437796">Chứng chỉ của máy chủ không hợp lệ tại thời điểm này.</translation>
 <translation id="5089810972385038852">Tiểu bang</translation>
 <translation id="5094747076828555589">Máy chủ này không chứng minh được rằng đó là <ph name="DOMAIN" />; chứng chỉ bảo mật của máy chủ này không được Chromium tin cậy. Điều này có thể do định cấu hình sai hoặc có kẻ tấn công chặn kết nối của bạn.</translation>
diff --git a/components/strings/components_strings_zh-CN.xtb b/components/strings/components_strings_zh-CN.xtb
index 3617b415..82780e6 100644
--- a/components/strings/components_strings_zh-CN.xtb
+++ b/components/strings/components_strings_zh-CN.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">后备存储状态不佳</translation>
 <translation id="5031870354684148875">关于 Google 翻译</translation>
 <translation id="5045550434625856497">密码不正确</translation>
+<translation id="5065199687811594072">您希望 Chromium 保存该信用卡信息以便填写网络表单吗?</translation>
 <translation id="5087286274860437796">服务器的证书目前无效。</translation>
 <translation id="5089810972385038852">州</translation>
 <translation id="5094747076828555589">此服务器无法证明它是<ph name="DOMAIN" />;Chromium不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
diff --git a/components/strings/components_strings_zh-TW.xtb b/components/strings/components_strings_zh-TW.xtb
index c5542137..1e42d34 100644
--- a/components/strings/components_strings_zh-TW.xtb
+++ b/components/strings/components_strings_zh-TW.xtb
@@ -179,6 +179,7 @@
 <translation id="5019198164206649151">備份儲存狀態不佳</translation>
 <translation id="5031870354684148875">關於「Google 翻譯」</translation>
 <translation id="5045550434625856497">密碼不正確</translation>
+<translation id="5065199687811594072">您希望 Chromium 儲存此信用卡資訊,方便您填妥網路表單嗎?</translation>
 <translation id="5087286274860437796">伺服器憑證目前無效。</translation>
 <translation id="5089810972385038852">州</translation>
 <translation id="5094747076828555589">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證未取得 Chromium 的信任。這可能是因為設定錯誤,或有攻擊者攔截您的連線所致。</translation>
diff --git a/components/translate/content/renderer/translate_helper.cc b/components/translate/content/renderer/translate_helper.cc
index 568ecf0..630778d 100644
--- a/components/translate/content/renderer/translate_helper.cc
+++ b/components/translate/content/renderer/translate_helper.cc
@@ -31,7 +31,6 @@
 #include "third_party/WebKit/public/web/WebElement.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebScriptSource.h"
 #include "url/gurl.h"
 #include "v8/include/v8.h"
@@ -41,7 +40,6 @@
 using blink::WebElement;
 using blink::WebLocalFrame;
 using blink::WebNode;
-using blink::WebNodeList;
 using blink::WebScriptSource;
 using blink::WebSecurityOrigin;
 using blink::WebString;
@@ -95,12 +93,11 @@
   const WebString value(ASCIIToUTF16("value"));
   const WebString content(ASCIIToUTF16("content"));
 
-  WebNodeList children = head.childNodes();
-  for (size_t i = 0; i < children.length(); ++i) {
-    WebNode node = children.item(i);
-    if (!node.isElementNode())
+  for (WebNode child = head.firstChild(); !child.isNull();
+      child = child.nextSibling()) {
+    if (!child.isElementNode())
       continue;
-    WebElement element = node.to<WebElement>();
+    WebElement element = child.to<WebElement>();
     // Check if a tag is <meta>.
     if (!element.hasHTMLTagName(meta))
       continue;
diff --git a/content/app/android/library_loader_hooks.cc b/content/app/android/library_loader_hooks.cc
index c26ee0d1..6f9d939 100644
--- a/content/app/android/library_loader_hooks.cc
+++ b/content/app/android/library_loader_hooks.cc
@@ -30,6 +30,7 @@
 #include "net/android/net_jni_registrar.h"
 #include "ui/android/ui_android_jni_registrar.h"
 #include "ui/base/android/ui_base_jni_registrar.h"
+#include "ui/events/android/events_jni_registrar.h"
 #include "ui/gfx/android/gfx_jni_registrar.h"
 #include "ui/gl/android/gl_jni_registrar.h"
 #include "ui/shell_dialogs/android/shell_dialogs_jni_registrar.h"
@@ -55,6 +56,9 @@
     if (!ui::gl::android::RegisterJni(env))
       return false;
 
+    if (!ui::events::android::RegisterJni(env))
+      return false;
+
     if (!ui::shell_dialogs::RegisterJni(env))
       return false;
 
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index 62b393c..557c8f3 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -35,7 +35,6 @@
 #include "content/browser/mojo/service_registry_android.h"
 #include "content/browser/power_save_blocker_android.h"
 #include "content/browser/renderer_host/ime_adapter_android.h"
-#include "content/browser/renderer_host/input/motion_event_android.h"
 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
 #include "content/browser/screen_orientation/screen_orientation_delegate_android.h"
 #include "content/browser/speech/speech_recognizer_impl_android.h"
@@ -83,8 +82,6 @@
     {"MediaResourceGetterImpl",
      content::MediaResourceGetterImpl::RegisterMediaResourceGetter},
     {"MediaSession", content::MediaSession::RegisterMediaSession},
-    {"MotionEventAndroid",
-     content::MotionEventAndroid::RegisterMotionEventAndroid},
     {"MotionEventSynthesizer",
      content::SyntheticGestureTargetAndroid::RegisterMotionEventSynthesizer},
     {"NavigationControllerAndroid",
diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc
index 9821566f..a775b14 100644
--- a/content/browser/android/content_startup_flags.cc
+++ b/content/browser/android/content_startup_flags.cc
@@ -8,13 +8,10 @@
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
 #include "base/sys_info.h"
 #include "cc/base/switches.h"
 #include "cc/trees/layer_tree_settings.h"
 #include "content/public/browser/android/compositor.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/common/content_constants.h"
 #include "content/public/common/content_switches.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "ui/base/ui_base_switches.h"
@@ -33,23 +30,7 @@
   base::CommandLine* parsed_command_line =
       base::CommandLine::ForCurrentProcess();
 
-  int command_line_renderer_limit = -1;
-  if (parsed_command_line->HasSwitch(switches::kRendererProcessLimit)) {
-    std::string limit = parsed_command_line->GetSwitchValueASCII(
-        switches::kRendererProcessLimit);
-    int value;
-    if (base::StringToInt(limit, &value)) {
-      command_line_renderer_limit = std::max(0, value);
-    }
-  }
-
-  if (command_line_renderer_limit > 0) {
-    int limit = std::min(command_line_renderer_limit,
-                         static_cast<int>(kMaxRendererProcessCount));
-    RenderProcessHost::SetMaxRendererProcessCount(limit);
-  }
-
-  if (single_process || command_line_renderer_limit == 0) {
+  if (single_process) {
     // Need to ensure the command line flag is consistent as a lot of chrome
     // internal code checks this directly, but it wouldn't normally get set when
     // we are implementing an embedded WebView.
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 18b8722..7aa79ee 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -25,7 +25,6 @@
 #include "content/browser/geolocation/geolocation_service_context.h"
 #include "content/browser/media/media_web_contents_observer.h"
 #include "content/browser/renderer_host/compositor_impl_android.h"
-#include "content/browser/renderer_host/input/motion_event_android.h"
 #include "content/browser/renderer_host/input/web_input_event_builders_android.h"
 #include "content/browser/renderer_host/input/web_input_event_util.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
@@ -52,6 +51,7 @@
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "ui/android/view_android.h"
 #include "ui/android/window_android.h"
+#include "ui/events/android/motion_event_android.h"
 #include "ui/gfx/android/java_bitmap.h"
 #include "ui/gfx/geometry/point_conversions.h"
 #include "ui/gfx/geometry/size_conversions.h"
@@ -893,7 +893,7 @@
   if (!rwhv)
     return false;
 
-  MotionEventAndroid::Pointer pointer0(pointer_id_0,
+  ui::MotionEventAndroid::Pointer pointer0(pointer_id_0,
                                        pos_x_0,
                                        pos_y_0,
                                        touch_major_0,
@@ -901,7 +901,7 @@
                                        orientation_0,
                                        tilt_0,
                                        android_tool_type_0);
-  MotionEventAndroid::Pointer pointer1(pointer_id_1,
+  ui::MotionEventAndroid::Pointer pointer1(pointer_id_1,
                                        pos_x_1,
                                        pos_y_1,
                                        touch_major_1,
@@ -909,7 +909,7 @@
                                        orientation_1,
                                        tilt_1,
                                        android_tool_type_1);
-  MotionEventAndroid event(1.f / dpi_scale(),
+  ui::MotionEventAndroid event(1.f / dpi_scale(),
                            env,
                            motion_event,
                            time_ms,
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
index bc13e95..497d7f77 100644
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
@@ -187,6 +187,23 @@
                           base::Bind(&base::DoNothing));
 }
 
+// TODO(ortuno): This should really be a BluetoothDevice method.
+// Replace when implemented. http://crbug.com/552022
+std::vector<BluetoothGattService*> GetPrimaryServicesByUUID(
+    device::BluetoothDevice* device,
+    const std::string& service_uuid) {
+  std::vector<BluetoothGattService*> services;
+  VLOG(1) << "Looking for service: " << service_uuid;
+  for (BluetoothGattService* service : device->GetGattServices()) {
+    VLOG(1) << "Service in cache: " << service->GetUUID().canonical_value();
+    if (service->GetUUID().canonical_value() == service_uuid &&
+        service->IsPrimary()) {
+      services.push_back(service);
+    }
+  }
+  return services;
+}
+
 }  //  namespace
 
 BluetoothDispatcherHost::BluetoothDispatcherHost(int render_process_id)
@@ -253,6 +270,7 @@
     scoped_refptr<device::BluetoothAdapter> mock_adapter) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   current_delay_time_ = kTestingDelayTime;
+  devices_with_discovered_services_.clear();
   // Reset the discovery session timer to use the new delay time.
   discovery_session_timer_.Start(
       FROM_HERE, base::TimeDelta::FromSecondsD(current_delay_time_),
@@ -340,6 +358,25 @@
   CacheQueryOutcome outcome;
 };
 
+struct BluetoothDispatcherHost::PrimaryServicesRequest {
+  enum CallingFunction { GET_PRIMARY_SERVICE, GET_PRIMARY_SERVICES };
+
+  PrimaryServicesRequest(int thread_id,
+                         int request_id,
+                         const std::string& service_uuid,
+                         PrimaryServicesRequest::CallingFunction func)
+      : thread_id(thread_id),
+        request_id(request_id),
+        service_uuid(service_uuid),
+        func(func) {}
+  ~PrimaryServicesRequest() {}
+
+  int thread_id;
+  int request_id;
+  std::string service_uuid;
+  CallingFunction func;
+};
+
 void BluetoothDispatcherHost::set_adapter(
     scoped_refptr<device::BluetoothAdapter> adapter) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -428,6 +465,49 @@
   }
 }
 
+void BluetoothDispatcherHost::GattServicesDiscovered(
+    device::BluetoothAdapter* adapter,
+    device::BluetoothDevice* device) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  const std::string& device_id = device->GetAddress();
+  VLOG(1) << "Services discovered for device: " << device_id;
+
+  devices_with_discovered_services_.insert(device_id);
+
+  auto iter = pending_primary_services_requests_.find(device_id);
+  if (iter == pending_primary_services_requests_.end()) {
+    return;
+  }
+  std::vector<PrimaryServicesRequest> requests;
+  requests.swap(iter->second);
+  pending_primary_services_requests_.erase(iter);
+
+  for (const PrimaryServicesRequest& request : requests) {
+    std::vector<BluetoothGattService*> services =
+        GetPrimaryServicesByUUID(device, request.service_uuid);
+    switch (request.func) {
+      case PrimaryServicesRequest::GET_PRIMARY_SERVICE:
+        if (!services.empty()) {
+          AddToServicesMapAndSendGetPrimaryServiceSuccess(
+              *services[0], request.thread_id, request.request_id);
+        } else {
+          VLOG(1) << "No service found";
+          RecordGetPrimaryServiceOutcome(
+              UMAGetPrimaryServiceOutcome::NOT_FOUND);
+          Send(new BluetoothMsg_GetPrimaryServiceError(
+              request.thread_id, request.request_id,
+              WebBluetoothError::ServiceNotFound));
+        }
+        break;
+      case PrimaryServicesRequest::GET_PRIMARY_SERVICES:
+        NOTIMPLEMENTED();
+        break;
+    }
+  }
+  DCHECK(!ContainsKey(pending_primary_services_requests_, device_id))
+      << "Sending get-service responses unexpectedly queued another request.";
+}
+
 void BluetoothDispatcherHost::GattCharacteristicValueChanged(
     device::BluetoothAdapter* adapter,
     device::BluetoothGattCharacteristic* characteristic,
@@ -584,7 +664,7 @@
   // permissions are implemented we should check that the domain has access to
   // the device. https://crbug.com/484745
 
-  CacheQueryResult query_result = CacheQueryResult();
+  CacheQueryResult query_result;
   QueryCacheForDevice(device_id, query_result);
 
   if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
@@ -616,14 +696,53 @@
   // https://crbug.com/493459
   // TODO(ortuno): Check if service_uuid is in "allowed services"
   // https://crbug.com/493460
-  // For now just wait a fixed time and call OnServiceDiscovered.
-  // TODO(ortuno): Use callback once it's implemented http://crbug.com/484504
-  BrowserThread::PostDelayedTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&BluetoothDispatcherHost::OnServicesDiscovered,
-                 weak_ptr_on_ui_thread_, thread_id, request_id, device_id,
-                 service_uuid),
-      base::TimeDelta::FromSeconds(current_delay_time_));
+
+  CacheQueryResult query_result;
+  QueryCacheForDevice(device_id, query_result);
+
+  if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
+    RecordGetPrimaryServiceOutcome(query_result.outcome);
+    Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id,
+                                                 query_result.GetWebError()));
+    return;
+  }
+
+  // There are four possibilities here:
+  // 1. Services not discovered and service present in |device|: Send back the
+  //    service to the renderer.
+  // 2. Services discovered and service present in |device|: Send back the
+  //    service to the renderer.
+  // 3. Services discovered and service not present in |device|: Send back not
+  //    found error.
+  // 4. Services not discovered and service not present in |device|: Add request
+  //    to map of pending getPrimaryService requests.
+
+  std::vector<BluetoothGattService*> services =
+      GetPrimaryServicesByUUID(query_result.device, service_uuid);
+
+  // 1. & 2.
+  if (!services.empty()) {
+    const BluetoothGattService& service = *services[0];
+    DCHECK(service.IsPrimary());
+    AddToServicesMapAndSendGetPrimaryServiceSuccess(service, thread_id,
+                                                    request_id);
+    return;
+  }
+
+  // 3.
+  if (IsServicesDiscoveryCompleteForDevice(device_id)) {
+    VLOG(1) << "No service found";
+    RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND);
+    Send(new BluetoothMsg_GetPrimaryServiceError(
+        thread_id, request_id, WebBluetoothError::ServiceNotFound));
+    return;
+  }
+
+  // 4.
+  AddToPendingPrimaryServicesRequest(
+      device_id,
+      PrimaryServicesRequest(thread_id, request_id, service_uuid,
+                             PrimaryServicesRequest::GET_PRIMARY_SERVICE));
 }
 
 void BluetoothDispatcherHost::OnGetCharacteristic(
@@ -635,7 +754,7 @@
   RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_CHARACTERISTIC);
   RecordGetCharacteristicCharacteristic(characteristic_uuid);
 
-  CacheQueryResult query_result = CacheQueryResult();
+  CacheQueryResult query_result;
   QueryCacheForService(service_instance_id, query_result);
 
   if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
@@ -684,7 +803,7 @@
   RecordWebBluetoothFunctionCall(
       UMAWebBluetoothFunction::CHARACTERISTIC_READ_VALUE);
 
-  CacheQueryResult query_result = CacheQueryResult();
+  CacheQueryResult query_result;
   QueryCacheForCharacteristic(characteristic_instance_id, query_result);
 
   if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
@@ -725,7 +844,7 @@
     return;
   }
 
-  CacheQueryResult query_result = CacheQueryResult();
+  CacheQueryResult query_result;
   QueryCacheForCharacteristic(characteristic_instance_id, query_result);
 
   if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
@@ -766,7 +885,7 @@
   // TODO(ortuno): Check if notify/indicate bit is set.
   // http://crbug.com/538869
 
-  CacheQueryResult query_result = CacheQueryResult();
+  CacheQueryResult query_result;
   QueryCacheForCharacteristic(characteristic_instance_id, query_result);
 
   if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
@@ -993,48 +1112,22 @@
                                          TranslateConnectError(error_code)));
 }
 
-void BluetoothDispatcherHost::OnServicesDiscovered(
+void BluetoothDispatcherHost::AddToServicesMapAndSendGetPrimaryServiceSuccess(
+    const device::BluetoothGattService& service,
     int thread_id,
-    int request_id,
-    const std::string& device_id,
-    const std::string& service_uuid) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    int request_id) {
+  const std::string& service_identifier = service.GetIdentifier();
+  const std::string& device_id = service.GetDevice()->GetAddress();
+  auto insert_result =
+      service_to_device_.insert(make_pair(service_identifier, device_id));
 
-  CacheQueryResult query_result = CacheQueryResult();
-  QueryCacheForDevice(device_id, query_result);
+  // If a value is already in map, DCHECK it's valid.
+  if (!insert_result.second)
+    DCHECK_EQ(insert_result.first->second, device_id);
 
-  if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
-    RecordGetPrimaryServiceOutcome(query_result.outcome);
-    Send(new BluetoothMsg_GetPrimaryServiceError(thread_id, request_id,
-                                                 query_result.GetWebError()));
-    return;
-  }
-
-  VLOG(1) << "Looking for service: " << service_uuid;
-  for (BluetoothGattService* service : query_result.device->GetGattServices()) {
-    VLOG(1) << "Service in cache: " << service->GetUUID().canonical_value();
-    if (service->GetUUID().canonical_value() == service_uuid) {
-      // TODO(ortuno): Use generated instance ID instead.
-      // https://crbug.com/495379
-      const std::string& service_identifier = service->GetIdentifier();
-      auto insert_result =
-          service_to_device_.insert(make_pair(service_identifier, device_id));
-
-      // If a value is already in map, DCHECK it's valid.
-      if (!insert_result.second)
-        DCHECK(insert_result.first->second == device_id);
-
-      RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS);
-      Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id,
-                                                     service_identifier));
-      return;
-    }
-  }
-
-  VLOG(1) << "No service found";
-  RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::NOT_FOUND);
-  Send(new BluetoothMsg_GetPrimaryServiceError(
-      thread_id, request_id, WebBluetoothError::ServiceNotFound));
+  RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome::SUCCESS);
+  Send(new BluetoothMsg_GetPrimaryServiceSuccess(thread_id, request_id,
+                                                 service_identifier));
 }
 
 void BluetoothDispatcherHost::OnCharacteristicValueRead(
@@ -1176,6 +1269,17 @@
   }
 }
 
+bool BluetoothDispatcherHost::IsServicesDiscoveryCompleteForDevice(
+    const std::string& device_id) {
+  return ContainsKey(devices_with_discovered_services_, device_id);
+}
+
+void BluetoothDispatcherHost::AddToPendingPrimaryServicesRequest(
+    const std::string& device_id,
+    const PrimaryServicesRequest& request) {
+  pending_primary_services_requests_[device_id].push_back(request);
+}
+
 void BluetoothDispatcherHost::ShowBluetoothOverviewLink() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   NOTIMPLEMENTED();
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.h b/content/browser/bluetooth/bluetooth_dispatcher_host.h
index 37db4f5..bea2a5ff8 100644
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.h
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.h
@@ -58,6 +58,7 @@
 
   struct CacheQueryResult;
   struct RequestDeviceSession;
+  struct PrimaryServicesRequest;
 
   // Set |adapter_| to a BluetoothAdapter instance and register observers,
   // releasing references to previous |adapter_|.
@@ -78,6 +79,8 @@
                    device::BluetoothDevice* device) override;
   void DeviceRemoved(device::BluetoothAdapter* adapter,
                      device::BluetoothDevice* device) override;
+  void GattServicesDiscovered(device::BluetoothAdapter* adapter,
+                              device::BluetoothDevice* device) override;
   void GattCharacteristicValueChanged(
       device::BluetoothAdapter* adapter,
       device::BluetoothGattCharacteristic* characteristic,
@@ -159,13 +162,12 @@
       base::TimeTicks start_time,
       device::BluetoothDevice::ConnectErrorCode error_code);
 
-  // Callback for future BluetoothAdapter::ServicesDiscovered callback:
-  // For now we just post a delayed task.
-  // See: https://crbug.com/484504
-  void OnServicesDiscovered(int thread_id,
-                            int request_id,
-                            const std::string& device_id,
-                            const std::string& service_uuid);
+  // Adds the service to the map of services' instance ids to devices' instance
+  // ids and sends the service to the renderer.
+  void AddToServicesMapAndSendGetPrimaryServiceSuccess(
+      const device::BluetoothGattService& service,
+      int thread_id,
+      int request_id);
 
   // Callbacks for BluetoothGattCharacteristic::ReadRemoteCharacteristic.
   void OnCharacteristicValueRead(int thread_id,
@@ -220,6 +222,18 @@
       const std::string& characteristic_instance_id,
       CacheQueryResult& result);
 
+  // Returns true if all services have been discovered for the device.
+  // When the host gets a ServiceChanged indication, it automatically
+  // re-discovers services, and only forwards the ServiceChanged event to this
+  // class when it's done re-discovering.
+  bool IsServicesDiscoveryCompleteForDevice(const std::string& device_id);
+
+  // Adds the PrimaryServicesRequest to the vector of pending services requests
+  // for that device.
+  void AddToPendingPrimaryServicesRequest(
+      const std::string& device_id,
+      const PrimaryServicesRequest& request);
+
   // Show help pages from the chooser dialog.
   void ShowBluetoothOverviewLink();
   void ShowBluetoothPairingLink();
@@ -268,6 +282,14 @@
   // TODO(scheib): Destroy as connections are closed. http://crbug.com/539643
   ScopedVector<device::BluetoothGattConnection> connections_;
 
+  // Keeps track of which devices have had their services discovered.
+  std::set<std::string> devices_with_discovered_services_;
+
+  // Map of device_id's to primary-services requests that need responses when
+  // that device's service discovery completes.
+  std::map<std::string, std::vector<PrimaryServicesRequest>>
+      pending_primary_services_requests_;
+
   // |weak_ptr_on_ui_thread_| provides weak pointers, e.g. for callbacks, and
   // because it exists and has been bound to the UI thread enforces that all
   // copies verify they are also used on the UI thread.
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index cef0842a..dc1fab38 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -1010,7 +1010,7 @@
   gfx::Rect translated_bounds(params.bounds);
   translated_bounds.Offset(guest_window_rect_.OffsetFromOrigin());
   BrowserPluginPopupMenuHelper popup_menu_helper(
-      owner_web_contents_->GetRenderViewHost(), render_frame_host);
+      owner_web_contents_->GetMainFrame(), render_frame_host);
   popup_menu_helper.ShowPopupMenu(translated_bounds,
                                   params.item_height,
                                   params.item_font_size,
diff --git a/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h b/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h
index 31c19803..600cb362 100644
--- a/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h
+++ b/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h
@@ -9,8 +9,6 @@
 
 namespace content {
 
-class RenderViewHost;
-class RenderViewHostImpl;
 class RenderFrameHost;
 class RenderFrameHostImpl;
 
@@ -19,15 +17,15 @@
 class BrowserPluginPopupMenuHelper : public PopupMenuHelper {
  public:
   // Creates a BrowserPluginPopupMenuHelper that positions popups relative to
-  // |embedder_rvh| and will notify |guest_rfh| when a user selects or cancels
+  // |embedder_rfh| and will notify |guest_rfh| when a user selects or cancels
   // the popup.
-  BrowserPluginPopupMenuHelper(RenderViewHost* embedder_rvh,
+  BrowserPluginPopupMenuHelper(RenderFrameHostImpl* embedder_rfh,
                                RenderFrameHost* guest_rfh);
 
  private:
   RenderWidgetHostViewMac* GetRenderWidgetHostView() const override;
 
-  RenderViewHostImpl* embedder_rvh_;
+  RenderFrameHostImpl* embedder_rfh_;
 
   DISALLOW_COPY_AND_ASSIGN(BrowserPluginPopupMenuHelper);
 };
diff --git a/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm b/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm
index 6817078c..1874747 100644
--- a/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm
+++ b/content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.mm
@@ -5,22 +5,19 @@
 #include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h"
 
 #include "content/browser/frame_host/render_frame_host_impl.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
 #include "content/public/browser/render_widget_host.h"
 
 namespace content {
 
 BrowserPluginPopupMenuHelper::BrowserPluginPopupMenuHelper(
-    RenderViewHost* embedder_rvh, RenderFrameHost* guest_rfh)
-    : PopupMenuHelper(guest_rfh),
-      embedder_rvh_(static_cast<RenderViewHostImpl*>(embedder_rvh)) {
-}
+    RenderFrameHostImpl* embedder_rfh,
+    RenderFrameHost* guest_rfh)
+    : PopupMenuHelper(guest_rfh), embedder_rfh_(embedder_rfh) {}
 
 RenderWidgetHostViewMac*
     BrowserPluginPopupMenuHelper::GetRenderWidgetHostView() const {
-  return static_cast<RenderWidgetHostViewMac*>(
-      embedder_rvh_->GetWidget()->GetView());
+  return static_cast<RenderWidgetHostViewMac*>(embedder_rfh_->GetView());
 }
 
 }  // namespace content
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc
index 26fbefe..911ae0d 100644
--- a/content/browser/frame_host/frame_tree.cc
+++ b/content/browser/frame_host/frame_tree.cc
@@ -244,7 +244,8 @@
         root()->render_manager()->CreateRenderFrameProxy(site_instance);
       } else {
         root()->render_manager()->CreateRenderFrame(
-            site_instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr);
+            site_instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
+            nullptr);
       }
     } else {
       root()->render_manager()->EnsureRenderViewInitialized(render_view_host,
diff --git a/content/browser/frame_host/popup_menu_helper_mac.mm b/content/browser/frame_host/popup_menu_helper_mac.mm
index 9826711..5cef607e1 100644
--- a/content/browser/frame_host/popup_menu_helper_mac.mm
+++ b/content/browser/frame_host/popup_menu_helper_mac.mm
@@ -9,6 +9,8 @@
 #include "base/mac/scoped_nsobject.h"
 #import "base/mac/scoped_sending_event.h"
 #include "base/message_loop/message_loop.h"
+#include "content/browser/frame_host/frame_tree.h"
+#include "content/browser/frame_host/frame_tree_node.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
@@ -119,7 +121,11 @@
 
 RenderWidgetHostViewMac* PopupMenuHelper::GetRenderWidgetHostView() const {
   return static_cast<RenderWidgetHostViewMac*>(
-      render_frame_host_->GetRenderViewHost()->GetWidget()->GetView());
+      render_frame_host_->frame_tree_node()
+          ->frame_tree()
+          ->root()
+          ->current_frame_host()
+          ->GetView());
 }
 
 void PopupMenuHelper::Observe(int type,
diff --git a/content/browser/frame_host/render_frame_host_delegate.cc b/content/browser/frame_host/render_frame_host_delegate.cc
index f33dc2c0..69b9e98 100644
--- a/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/content/browser/frame_host/render_frame_host_delegate.cc
@@ -76,11 +76,6 @@
   return false;
 }
 
-scoped_ptr<WebUIImpl> RenderFrameHostDelegate::CreateWebUIForRenderFrameHost(
-    const GURL& url) {
-  return nullptr;
-}
-
 #if defined(OS_WIN)
 gfx::NativeViewAccessible
     RenderFrameHostDelegate::GetParentNativeViewAccessible() {
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
index 5c59b90..13f78d9c 100644
--- a/content/browser/frame_host/render_frame_host_delegate.h
+++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -9,7 +9,6 @@
 
 #include "base/basictypes.h"
 #include "base/i18n/rtl.h"
-#include "content/browser/webui/web_ui_impl.h"
 #include "content/common/content_export.h"
 #include "content/common/frame_message_enums.h"
 #include "content/public/browser/site_instance.h"
@@ -173,10 +172,6 @@
   // https://crbug.com/330264.
   virtual void EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) {}
 
-  // Creates a WebUI object for a frame navigating to the given URL. If no WebUI
-  // applies, returns null.
-  virtual scoped_ptr<WebUIImpl> CreateWebUIForRenderFrameHost(const GURL& url);
-
 #if defined(OS_WIN)
   // Returns the frame's parent's NativeViewAccessible.
   virtual gfx::NativeViewAccessible GetParentNativeViewAccessible();
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 5d5be24..0928d4dad 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -16,7 +16,6 @@
 #include "content/browser/accessibility/browser_accessibility_manager.h"
 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
 #include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
 #include "content/browser/frame_host/cross_process_frame_connector.h"
 #include "content/browser/frame_host/cross_site_transferring_request.h"
@@ -43,7 +42,6 @@
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/wake_lock/wake_lock_service_context.h"
-#include "content/browser/webui/web_ui_controller_factory_registry.h"
 #include "content/common/accessibility_messages.h"
 #include "content/common/frame_messages.h"
 #include "content/common/input_messages.h"
@@ -196,7 +194,6 @@
       accessibility_reset_token_(0),
       accessibility_reset_count_(0),
       no_create_browser_accessibility_manager_for_testing_(false),
-      web_ui_type_(WebUI::kNoWebUI),
       weak_ptr_factory_(this) {
   bool is_swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
   bool hidden = !!(flags & CREATE_RF_HIDDEN);
@@ -236,10 +233,6 @@
 }
 
 RenderFrameHostImpl::~RenderFrameHostImpl() {
-  // Release the WebUI before all else as the WebUI accesses the RenderFrameHost
-  // during cleanup.
-  ResetWebUI();
-
   GetProcess()->RemoveRoute(routing_id_);
   g_routing_id_frame_map.Get().erase(
       RenderFrameHostID(GetProcess()->GetID(), routing_id_));
@@ -1223,7 +1216,6 @@
   TRACE_EVENT_ASYNC_END0("navigation", "RenderFrameHostImpl::SwapOut", this);
   swapout_event_monitor_timeout_->Stop();
 
-  ResetWebUI();
 
   // If this is a main frame RFH that's about to be deleted, update its RVH's
   // swapped-out state here, since SetState won't be called once this RFH is
@@ -1408,8 +1400,10 @@
 void RenderFrameHostImpl::OnUpdateTitle(
     const base::string16& title,
     blink::WebTextDirection title_direction) {
-  // This message is only sent for top-level frames. TODO(avi): when frame tree
-  // mirroring works correctly, add a check here to enforce it.
+  // This message should only be sent for top-level frames.
+  if (frame_tree_node_->parent())
+    return;
+
   if (title.length() > kMaxTitleChars) {
     NOTREACHED() << "Renderer sent too many characters in title.";
     return;
@@ -2055,65 +2049,6 @@
           frame_tree_->GetFocusedFrame()->IsDescendantOf(frame_tree_node()));
 }
 
-bool RenderFrameHostImpl::UpdateWebUI(const GURL& dest_url,
-                                      int entry_bindings) {
-  WebUI::TypeID new_web_ui_type = WebUI::kNoWebUI;
-  if (dest_url.is_valid()) {
-    new_web_ui_type =
-        WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
-            GetSiteInstance()->GetBrowserContext(), dest_url);
-  }
-
-  WebUIImpl* prev_web_ui = web_ui_.get();
-  if (new_web_ui_type == WebUI::kNoWebUI) {
-    ResetWebUI();
-  } else {
-    // The current WebUI should be reused when dest_url requires a WebUI and its
-    // type matches the current. Otherwise replace it with a new one.
-    if (web_ui_type_ != new_web_ui_type) {
-      web_ui_ = delegate_->CreateWebUIForRenderFrameHost(dest_url);
-      DCHECK(web_ui_);
-      web_ui_type_ = new_web_ui_type;
-
-      // If we have assigned (zero or more) bindings to the NavigationEntry in
-      // the past, make sure we're not granting it different bindings than it
-      // had before. If so, note it and don't give it any bindings, to avoid a
-      // potential privilege escalation.
-      if (entry_bindings != NavigationEntryImpl::kInvalidBindings &&
-          web_ui_->GetBindings() != entry_bindings) {
-        RecordAction(
-            base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
-        ResetWebUI();
-        return !!prev_web_ui;
-      }
-    }
-  }
-  DCHECK_EQ(!web_ui_, web_ui_type_ == WebUI::kNoWebUI);
-
-  // Check RenderViewHost for proper bindings.
-  if (web_ui_ && !render_view_host_->GetProcess()->IsForGuestsOnly()) {
-    // If a WebUI was created for the URL and the RenderView is not in a guest
-    // process, then enable missing bindings with the RenderViewHost.
-    int new_bindings = web_ui_->GetBindings();
-    if ((render_view_host_->GetEnabledBindings() & new_bindings) !=
-        new_bindings) {
-      render_view_host_->AllowBindings(new_bindings);
-    }
-  } else if (render_view_host_->is_active()) {
-    // If the ongoing navigation is not to a WebUI or the RenderView is in a
-    // guest process, ensure that we don't create an unprivileged RenderView in
-    // a WebUI-enabled process unless it's swapped out.
-    bool url_acceptable_for_webui =
-        WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
-            GetSiteInstance()->GetBrowserContext(), dest_url);
-    if (!url_acceptable_for_webui) {
-      CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
-          GetProcess()->GetID()));
-    }
-  }
-  return prev_web_ui != web_ui_.get();
-}
-
 const image_downloader::ImageDownloaderPtr&
 RenderFrameHostImpl::GetMojoImageDownloader() {
   if (!mojo_image_downloader_.get() && GetServiceRegistry()) {
@@ -2425,9 +2360,4 @@
     dst->parent_tree_id = RoutingIDToAXTreeID(src.parent_routing_id);
 }
 
-void RenderFrameHostImpl::ResetWebUI() {
-  web_ui_type_ = WebUI::kNoWebUI;
-  web_ui_.reset();
-}
-
 }  // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 1afa1617..41f0bce 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -17,7 +17,6 @@
 #include "content/browser/accessibility/browser_accessibility_manager.h"
 #include "content/browser/bad_message.h"
 #include "content/browser/site_instance_impl.h"
-#include "content/browser/webui/web_ui_impl.h"
 #include "content/common/accessibility_mode_enums.h"
 #include "content/common/ax_content_node_data.h"
 #include "content/common/content_export.h"
@@ -219,12 +218,6 @@
   RenderFrameHostDelegate* delegate() { return delegate_; }
   FrameTreeNode* frame_tree_node() { return frame_tree_node_; }
 
-  // Returns the associated WebUI or null if none applies.
-  WebUIImpl* web_ui() const { return web_ui_.get(); }
-
-  // Returns the associated WebUI type.
-  WebUI::TypeID web_ui_type() const { return web_ui_type_; }
-
   // Returns this RenderFrameHost's loading state. This method is only used by
   // FrameTreeNode. The proper way to check whether a frame is loading is to
   // call FrameTreeNode::IsLoading.
@@ -485,15 +478,6 @@
   // addition, its associated RenderWidgetHost has to be focused.
   bool IsFocused();
 
-  // Updates the WebUI of this RenderFrameHost based on the provided |dest_url|,
-  // setting it to either none, a new instance or simply reuses the currently
-  // existing one. Returns true if a WebUI change occurred.
-  // If this is a history navigation its NavigationEntry bindings should be
-  // provided through |entry_bindings| to allow verifying that they are not
-  // being set differently this time around. Otherwise |entry_bindings| should
-  // be set to NavigationEntryImpl::kInvalidBindings so that no checks are done.
-  bool UpdateWebUI(const GURL& dest_url, int entry_bindings);
-
   // Returns the Mojo ImageDownloader service.
   const image_downloader::ImageDownloaderPtr& GetMojoImageDownloader();
 
@@ -664,9 +648,6 @@
   FrameTreeNode* FindAndVerifyChild(
       int32 child_frame_routing_id, bad_message::BadMessageReason reason);
 
-  // Resets all WebUI related fields.
-  void ResetWebUI();
-
   // For now, RenderFrameHosts indirectly keep RenderViewHosts alive via a
   // refcount that calls Shutdown when it reaches zero.  This allows each
   // RenderFrameHostManager to just care about RenderFrameHosts, while ensuring
@@ -842,12 +823,6 @@
   // NavigationHandle for it is owned by the NavigationRequest.
   scoped_ptr<NavigationHandleImpl> navigation_handle_;
 
-  // The associated WebUIImpl and its type. They will be set if the current
-  // document or the one being navigated to is from WebUI source. Otherwise they
-  // will be null and WebUI::kNoWebUI, respectively.
-  scoped_ptr<WebUIImpl> web_ui_;
-  WebUI::TypeID web_ui_type_;
-
   // NOTE: This must be the last member.
   base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_;
 
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index e4c7fd7..1f6101d3 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -30,6 +30,7 @@
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/browser/webui/web_ui_controller_factory_registry.h"
+#include "content/browser/webui/web_ui_impl.h"
 #include "content/common/frame_messages.h"
 #include "content/common/site_isolation_policy.h"
 #include "content/common/view_messages.h"
@@ -38,6 +39,7 @@
 #include "content/public/browser/render_widget_host_iterator.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/user_metrics.h"
+#include "content/public/browser/web_ui_controller.h"
 #include "content/public/common/browser_plugin_guest_mode.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/referrer.h"
@@ -218,7 +220,7 @@
       render_widget_delegate_(render_widget_delegate),
       proxy_hosts_(new RenderFrameProxyHostMap(this)),
       interstitial_page_(nullptr),
-      current_web_ui_is_navigating_(false),
+      should_reuse_web_ui_(false),
       weak_factory_(this) {
   DCHECK(frame_tree_node_);
 }
@@ -243,6 +245,10 @@
   // the current RenderFrameHost and uses it during its destructor.
   ResetProxyHosts();
 
+  // Release the WebUI prior to resetting the current RenderFrameHost, as the
+  // WebUI accesses the RenderFrameHost during cleanup.
+  web_ui_.reset();
+
   // We should always have a current RenderFrameHost except in some tests.
   SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>());
 }
@@ -283,21 +289,6 @@
   return pending_render_frame_host_->render_view_host();
 }
 
-WebUIImpl* RenderFrameHostManager::GetNavigatingWebUI() const {
-  if (current_web_ui_is_navigating_)
-    return render_frame_host_->web_ui();
-
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableBrowserSideNavigation)) {
-    if (speculative_render_frame_host_)
-      return speculative_render_frame_host_->web_ui();
-  } else {
-    if (pending_render_frame_host_)
-      return pending_render_frame_host_->web_ui();
-  }
-  return nullptr;
-}
-
 RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const {
   if (interstitial_page_)
     return interstitial_page_->GetView();
@@ -366,6 +357,27 @@
       outer_delegate_frame_tree_node);
 }
 
+void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) {
+  pending_web_ui_ = CreateWebUI(url, bindings);
+  pending_and_current_web_ui_.reset();
+}
+
+scoped_ptr<WebUIImpl> RenderFrameHostManager::CreateWebUI(const GURL& url,
+                                                          int bindings) {
+  scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url));
+
+  // If we have assigned (zero or more) bindings to this NavigationEntry in the
+  // past, make sure we're not granting it different bindings than it had
+  // before.  If so, note it and don't give it any bindings, to avoid a
+  // potential privilege escalation.
+  if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings &&
+      new_web_ui->GetBindings() != bindings) {
+    RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
+    return nullptr;
+  }
+  return new_web_ui.Pass();
+}
+
 RenderFrameHostImpl* RenderFrameHostManager::Navigate(
     const GURL& dest_url,
     const FrameNavigationEntry& frame_entry,
@@ -414,11 +426,6 @@
     if (!InitRenderView(dest_render_frame_host->render_view_host(), nullptr))
       return nullptr;
 
-    if (GetNavigatingWebUI()) {
-      GetNavigatingWebUI()->RenderViewCreated(
-          dest_render_frame_host->render_view_host());
-    }
-
     // Now that we've created a new renderer, be sure to hide it if it isn't
     // our primary one.  Otherwise, we might crash if we try to call Show()
     // on it later.
@@ -669,14 +676,13 @@
     RenderFrameHostImpl* render_frame_host,
     bool was_caused_by_user_gesture) {
   if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
-    DCHECK(!current_web_ui_is_navigating_ || render_frame_host_->web_ui());
+    DCHECK(!should_reuse_web_ui_ || web_ui_);
 
     // We should only hear this from our current renderer.
     DCHECK_EQ(render_frame_host_, render_frame_host);
 
-    // A commit is required if there is a navigating WebUI, even without a
-    // pending or speculative RenderFrameHost.
-    if (GetNavigatingWebUI())
+    // Even when there is no pending RVH, there may be a pending Web UI.
+    if (pending_web_ui() || speculative_web_ui_)
       CommitPending();
     return;
   }
@@ -1019,44 +1025,41 @@
       (!request.browser_initiated() && is_main_frame) ||
       (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() &&
        !current_site_instance->RequiresDedicatedProcess())) {
-    // Reuse the current RenderFrameHost if its SiteInstance matches the the
-    // navigation's or if this is a subframe navigation. We only swap RFHs for
-    // subframes when --site-per-process is enabled.
+    // Reuse the current RFH if its SiteInstance matches the the navigation's
+    // or if this is a subframe navigation. We only swap RFHs for subframes when
+    // --site-per-process is enabled.
     CleanUpNavigation();
     navigation_rfh = render_frame_host_.get();
 
-    UpdateWebUIOnCurrentFrameHost(
-        request.common_params().url,
-        request.restore_type() != NavigationEntryImpl::RESTORE_NONE,
-        request.bindings());
-
-    DCHECK(!speculative_render_frame_host_);
+    // As SiteInstances are the same, check if the WebUI should be reused.
+    const NavigationEntry* current_navigation_entry =
+        delegate_->GetLastCommittedNavigationEntryForRenderManager();
+    should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry,
+                                            request.common_params().url);
+    if (!should_reuse_web_ui_) {
+      speculative_web_ui_ = CreateWebUI(request.common_params().url,
+                                        request.bindings());
+      // Make sure the current RenderViewHost has the right bindings.
+      if (speculative_web_ui() &&
+          !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
+        render_frame_host_->render_view_host()->AllowBindings(
+            speculative_web_ui()->GetBindings());
+      }
+    }
   } else {
-    // If the current RenderFrameHost cannot be used a new speculative one is
-    // created with the SiteInstance for the current URL.
-
-    // Check if an existing speculative RenderFrameHost can be reused.
+    // If the SiteInstance for the final URL doesn't match the one from the
+    // speculatively created RenderFrameHost, create a new RenderFrameHost using
+    // this new SiteInstance.
     if (!speculative_render_frame_host_ ||
         speculative_render_frame_host_->GetSiteInstance() !=
             dest_site_instance.get()) {
-      // If a previous speculative RenderFrameHost didn't exist or if its
-      // SiteInstace differs from the one for the current URL, a new one needs
-      // to be created.
       CleanUpNavigation();
-      bool success = CreateSpeculativeRenderFrameHost(current_site_instance,
-                                                      dest_site_instance.get());
+      bool success = CreateSpeculativeRenderFrameHost(
+          request.common_params().url, current_site_instance,
+          dest_site_instance.get(), request.bindings());
       DCHECK(success);
     }
-
-    bool changed_web_ui = speculative_render_frame_host_->UpdateWebUI(
-        request.common_params().url, request.bindings());
-    if (changed_web_ui && speculative_render_frame_host_->web_ui()) {
-      speculative_render_frame_host_->web_ui()->RenderViewCreated(
-          speculative_render_frame_host_->render_view_host());
-    }
     DCHECK(speculative_render_frame_host_);
-    DCHECK_EQ(GetNavigatingWebUI(), speculative_render_frame_host_->web_ui());
-
     navigation_rfh = speculative_render_frame_host_.get();
 
     // Check if our current RFH is live.
@@ -1068,7 +1071,6 @@
       // RFH isn't live.)
       CommitPending();
     }
-    DCHECK(!current_web_ui_is_navigating_);
   }
   DCHECK(navigation_rfh &&
          (navigation_rfh == render_frame_host_.get() ||
@@ -1079,12 +1081,8 @@
   if (!navigation_rfh->IsRenderFrameLive()) {
     // Recreate the opener chain.
     CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_);
-    if (!InitRenderView(navigation_rfh->render_view_host(), nullptr))
+    if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) {
       return nullptr;
-
-    if (GetNavigatingWebUI()) {
-      GetNavigatingWebUI()->RenderViewCreated(
-          navigation_rfh->render_view_host());
     }
 
     if (navigation_rfh == render_frame_host_) {
@@ -1106,9 +1104,8 @@
 void RenderFrameHostManager::CleanUpNavigation() {
   CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kEnableBrowserSideNavigation));
-  // TODO(carlosk): the discarding of the current RFH WebUI and the cleanup of
-  // the speculative RFH should not always happen together.
-  current_web_ui_is_navigating_ = false;
+  speculative_web_ui_.reset();
+  should_reuse_web_ui_ = false;
   if (speculative_render_frame_host_)
     DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
 }
@@ -1301,6 +1298,18 @@
   return false;
 }
 
+bool RenderFrameHostManager::ShouldReuseWebUI(
+    const NavigationEntry* current_entry,
+    const GURL& new_url) const {
+  NavigationControllerImpl& controller =
+      delegate_->GetControllerForRenderManager();
+  return current_entry && web_ui_ &&
+      (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
+          controller.GetBrowserContext(), current_entry->GetURL()) ==
+       WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
+          controller.GetBrowserContext(), new_url));
+}
+
 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
     const GURL& dest_url,
     SiteInstance* source_instance,
@@ -1633,8 +1642,8 @@
   CreateProxiesForNewRenderFrameHost(old_instance, new_instance);
 
   // Create a non-swapped-out RFH with the given opener.
-  pending_render_frame_host_ =
-      CreateRenderFrame(new_instance, create_render_frame_flags, nullptr);
+  pending_render_frame_host_ = CreateRenderFrame(
+      new_instance, pending_web_ui(), create_render_frame_flags, nullptr);
 }
 
 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
@@ -1730,11 +1739,18 @@
 
 // PlzNavigate
 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
+    const GURL& url,
     SiteInstance* old_instance,
-    SiteInstance* new_instance) {
+    SiteInstance* new_instance,
+    int bindings) {
   CHECK(new_instance);
   CHECK_NE(old_instance, new_instance);
-  CHECK(!current_web_ui_is_navigating_);
+  CHECK(!should_reuse_web_ui_);
+
+  // Note: |speculative_web_ui_| must be initialized before starting the
+  // |speculative_render_frame_host_| creation steps otherwise the WebUI
+  // won't be properly initialized.
+  speculative_web_ui_ = CreateWebUI(url, bindings);
 
   // The process for the new SiteInstance may (if we're sharing a process with
   // another host that already initialized it) or may not (we have our own
@@ -1749,13 +1765,19 @@
   if (delegate_->IsHidden())
     create_render_frame_flags |= CREATE_RF_HIDDEN;
   speculative_render_frame_host_ =
-      CreateRenderFrame(new_instance, create_render_frame_flags, nullptr);
+      CreateRenderFrame(new_instance, speculative_web_ui_.get(),
+                        create_render_frame_flags, nullptr);
 
-  return !!speculative_render_frame_host_;
+  if (!speculative_render_frame_host_) {
+    speculative_web_ui_.reset();
+    return false;
+  }
+  return true;
 }
 
 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
     SiteInstance* instance,
+    WebUIImpl* web_ui,
     int flags,
     int* view_routing_id_ptr) {
   bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
@@ -1873,6 +1895,21 @@
     }
   }
 
+  // When a new RenderView is created by the renderer process, the new
+  // WebContents gets a RenderViewHost in the SiteInstance of its opener
+  // WebContents. If not used in the first navigation, this RVH is swapped out
+  // and is not granted bindings, so we may need to grant them when swapping it
+  // in.
+  if (web_ui && !new_render_frame_host->GetProcess()->IsForGuestsOnly()) {
+    int required_bindings = web_ui->GetBindings();
+    RenderViewHost* render_view_host =
+        new_render_frame_host->render_view_host();
+    if ((render_view_host->GetEnabledBindings() & required_bindings) !=
+            required_bindings) {
+      render_view_host->AllowBindings(required_bindings);
+    }
+  }
+
   // Returns the new RFH if it isn't swapped out.
   if (success && !swapped_out) {
     DCHECK(new_render_frame_host->GetSiteInstance() == instance);
@@ -1991,6 +2028,31 @@
   if (render_view_host->IsRenderViewLive())
     return true;
 
+  // If |render_view_host| is not for a proxy and the navigation is to a WebUI,
+  // and if the RenderView is not in a guest process, tell |render_view_host|
+  // about any bindings it will need enabled.
+  // TODO(carlosk): Move WebUI to RenderFrameHost in https://crbug.com/508850.
+  WebUIImpl* dest_web_ui = nullptr;
+  if (!proxy) {
+    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+            switches::kEnableBrowserSideNavigation)) {
+      dest_web_ui =
+          should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
+    } else {
+      dest_web_ui = pending_web_ui();
+    }
+  }
+  if (dest_web_ui && !render_view_host->GetProcess()->IsForGuestsOnly()) {
+    render_view_host->AllowBindings(dest_web_ui->GetBindings());
+  } else {
+    // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
+    // process unless it's swapped out.
+    if (render_view_host->is_active()) {
+      CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+                render_view_host->GetProcess()->GetID()));
+    }
+  }
+
   int opener_frame_routing_id =
       GetOpenerRoutingID(render_view_host->GetSiteInstance());
 
@@ -2082,17 +2144,42 @@
 void RenderFrameHostManager::CommitPending() {
   TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
                "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
+  bool browser_side_navigation =
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableBrowserSideNavigation);
+
   // First check whether we're going to want to focus the location bar after
   // this commit.  We do this now because the navigation hasn't formally
-  // committed yet, so if we've already cleared the pending WebUI the call chain
+  // committed yet, so if we've already cleared |pending_web_ui_| the call chain
   // this triggers won't be able to figure out what's going on.
   bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
 
+  // Next commit the Web UI, if any. Either replace |web_ui_| with
+  // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
+  // leave |web_ui_| as is if reusing it.
+  DCHECK(!(pending_web_ui_ && pending_and_current_web_ui_));
+  if (pending_web_ui_ || speculative_web_ui_) {
+    DCHECK(!should_reuse_web_ui_);
+    web_ui_.reset(browser_side_navigation ? speculative_web_ui_.release()
+                                          : pending_web_ui_.release());
+  } else if (pending_and_current_web_ui_ || should_reuse_web_ui_) {
+    if (browser_side_navigation) {
+      DCHECK(web_ui_);
+      should_reuse_web_ui_ = false;
+    } else {
+      DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
+      pending_and_current_web_ui_.reset();
+    }
+  } else {
+    web_ui_.reset();
+  }
+  DCHECK(!speculative_web_ui_);
+  DCHECK(!should_reuse_web_ui_);
+
+  // It's possible for the pending_render_frame_host_ to be nullptr when we
+  // aren't crossing process boundaries. If so, we just needed to handle the Web
+  // UI committing above and we're done.
   if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
-    DCHECK_EQ(current_web_ui_is_navigating_, !!render_frame_host_->web_ui());
-    current_web_ui_is_navigating_ = false;
-    // If there's no pending/speculative RenderFrameHost then the current
-    // RenderFrameHost is committing.
     if (will_focus_location_bar)
       delegate_->SetFocusToLocationBar(false);
     return;
@@ -2109,8 +2196,7 @@
   // Swap in the pending or speculative frame and make it active. Also ensure
   // the FrameTree stays in sync.
   scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
-  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableBrowserSideNavigation)) {
+  if (!browser_side_navigation) {
     DCHECK(!speculative_render_frame_host_);
     old_render_frame_host =
         SetRenderFrameHost(pending_render_frame_host_.Pass());
@@ -2280,6 +2366,9 @@
       dest_url, source_instance, dest_instance, nullptr, transition,
       dest_is_restore, dest_is_view_source_mode);
 
+  const NavigationEntry* current_entry =
+      delegate_->GetLastCommittedNavigationEntryForRenderManager();
+
   DCHECK(!pending_render_frame_host_);
 
   if (new_instance.get() != current_instance) {
@@ -2292,21 +2381,17 @@
 
     // New SiteInstance: create a pending RFH to navigate.
 
-    current_web_ui_is_navigating_ = false;
+    // This will possibly create (set to nullptr) a Web UI object for the
+    // pending page. We'll use this later to give the page special access. This
+    // must happen before the new renderer is created below so it will get
+    // bindings. It must also happen after the above conditional call to
+    // CancelPending(), otherwise CancelPending may clear the pending_web_ui_
+    // and the page will not have its bindings set appropriately.
+    SetPendingWebUI(dest_url, bindings);
     CreatePendingRenderFrameHost(current_instance, new_instance.get());
-    DCHECK(pending_render_frame_host_);
     if (!pending_render_frame_host_)
       return nullptr;
 
-    pending_render_frame_host_->UpdateWebUI(dest_url, bindings);
-    if (pending_render_frame_host_->web_ui()) {
-      pending_render_frame_host_->web_ui()->RenderViewCreated(
-          pending_render_frame_host_->render_view_host());
-    }
-
-    // We now have a pending RFH and possibly an associated pending WebUI.
-    DCHECK_EQ(GetNavigatingWebUI(), pending_render_frame_host_->web_ui());
-
     // Check if our current RFH is live before we set up a transition.
     if (!render_frame_host_->IsRenderFrameLive()) {
       // The current RFH is not live.  There's no reason to sit around with a
@@ -2319,12 +2404,16 @@
     }
     // Otherwise, it's safe to treat this as a pending cross-process transition.
 
+    // We now have a pending RFH.
+    DCHECK(pending_render_frame_host_);
+
     // We need to wait until the beforeunload handler has run, unless we are
     // transferring an existing request (in which case it has already run).
     // Suspend the new render view (i.e., don't let it send the cross-process
     // Navigate message) until we hear back from the old renderer's
     // beforeunload handler.  If the handler returns false, we'll have to
     // cancel the request.
+    //
     DCHECK(!pending_render_frame_host_->are_navigations_suspended());
     bool is_transfer = transferred_request_id != GlobalRequestID();
     if (is_transfer) {
@@ -2359,7 +2448,23 @@
   // delete the proxy.
   proxy_hosts_->Remove(new_instance.get()->GetId());
 
-  UpdateWebUIOnCurrentFrameHost(dest_url, dest_is_restore, bindings);
+  if (ShouldReuseWebUI(current_entry, dest_url)) {
+    pending_web_ui_.reset();
+    pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
+  } else {
+    SetPendingWebUI(dest_url, bindings);
+    // Make sure the new RenderViewHost has the right bindings.
+    if (pending_web_ui() &&
+        !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
+      render_frame_host_->render_view_host()->AllowBindings(
+          pending_web_ui()->GetBindings());
+    }
+  }
+
+  if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) {
+    pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(),
+                                       frame_tree_node_->IsMainFrame());
+  }
 
   // The renderer can exit view source mode when any error or cancellation
   // happen. We must overwrite to recover the mode.
@@ -2372,39 +2477,9 @@
   return render_frame_host_.get();
 }
 
-void RenderFrameHostManager::UpdateWebUIOnCurrentFrameHost(const GURL& dest_url,
-                                                           bool dest_is_restore,
-                                                           int bindings) {
-  WebUI::TypeID previous_web_ui_type = render_frame_host_->web_ui_type();
-  bool changed_web_ui = render_frame_host_->UpdateWebUI(dest_url, bindings);
-
-  // If a change in WebUI happened, check this is an acceptable case.
-  if (changed_web_ui)
-    CheckWebUITransition(previous_web_ui_type, dest_url, dest_is_restore);
-
-  // If there is a WebUI in the current RenderFrameHost, it will navigate.
-  current_web_ui_is_navigating_ = !!render_frame_host_->web_ui();
-  DCHECK_EQ(GetNavigatingWebUI(), render_frame_host_->web_ui());
-
-  // If the current RenderFrameHost has a WebUI and the associated RenderFrame
-  // is alive, notify to the WebUI that the RenderView is being created or
-  // reused depending on whether the WebUI was changed or not.
-  if (GetNavigatingWebUI() && render_frame_host_->IsRenderFrameLive()) {
-    if (changed_web_ui) {
-      GetNavigatingWebUI()->RenderViewCreated(
-          render_frame_host_->render_view_host());
-    } else {
-      GetNavigatingWebUI()->RenderViewReused(
-          render_frame_host_->render_view_host(),
-          frame_tree_node_->IsMainFrame());
-    }
-  }
-}
-
 void RenderFrameHostManager::CancelPending() {
   TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending",
                "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
-  current_web_ui_is_navigating_ = false;
   DiscardUnusedFrame(UnsetPendingRenderFrameHost());
 }
 
@@ -2417,11 +2492,12 @@
       pending_render_frame_host.get(),
       render_frame_host_.get());
 
-  current_web_ui_is_navigating_ = false;
-
   // We no longer need to prevent the process from exiting.
   pending_render_frame_host->GetProcess()->RemovePendingView();
 
+  pending_web_ui_.reset();
+  pending_and_current_web_ui_.reset();
+
   return pending_render_frame_host.Pass();
 }
 
@@ -2596,7 +2672,8 @@
         frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance);
       } else {
         frame_tree->root()->render_manager()->CreateRenderFrame(
-            instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr);
+            instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
+            nullptr);
       }
     }
   }
@@ -2611,51 +2688,4 @@
       ->GetRoutingIdForSiteInstance(instance);
 }
 
-void RenderFrameHostManager::CheckWebUITransition(
-    WebUI::TypeID previous_web_ui_type,
-    const GURL& dest_url,
-    bool dest_is_restore) {
-  // There are a few navigation cases that allow for changes to the WebUI of
-  // the current RenderFrameHost.
-  BrowserContext* browser_context =
-      delegate_->GetControllerForRenderManager().GetBrowserContext();
-  if (render_frame_host_->web_ui()) {
-    // Switching WebUI from one type to another while keeping the
-    // RenderFrameHost is never acceptable.
-    CHECK(previous_web_ui_type == WebUI::kNoWebUI);
-
-    // Going from not having to having a WebUI is acceptable for:
-    // - The first navigation of this frame.
-    const NavigationEntry* current_entry =
-        delegate_->GetLastCommittedNavigationEntryForRenderManager();
-    bool is_first_navigation_for_frame = !current_entry;
-
-    // - A restore navigation to a WebUI URL.
-    const GURL& current_effective_url =
-        current_entry ? SiteInstanceImpl::GetEffectiveURL(
-                            browser_context, current_entry->GetURL())
-                      : render_frame_host_->GetSiteInstance()->GetSiteURL();
-    bool is_webui_restore =
-        dest_is_restore &&
-        WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
-            browser_context, current_effective_url);
-
-    // - Navigating back from a special renderer URL.
-    bool is_back_from_renderer_url =
-        current_entry && IsRendererDebugURL(current_entry->GetURL());
-
-    // - Navigating in webview tag guest.
-    bool is_webview_tag_guest =
-        render_frame_host_->GetSiteInstance()->GetSiteURL().SchemeIs(
-            kGuestScheme);
-    CHECK(is_first_navigation_for_frame || is_webui_restore ||
-          is_back_from_renderer_url || is_webview_tag_guest);
-  } else {
-    // Going from having to not having a WebUI is acceptable when Navigating to
-    // a special renderer URL.
-    CHECK(IsRendererDebugURL(
-        SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url)));
-  }
-}
-
 }  // namespace content
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h
index 1c6c405d..ae64247 100644
--- a/content/browser/frame_host/render_frame_host_manager.h
+++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -12,7 +12,6 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_delegate.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/common/content_export.h"
@@ -34,7 +33,9 @@
 class NavigationHandleImpl;
 class NavigationRequest;
 class NavigatorTestWithBrowserSideNavigation;
+class RenderFrameHost;
 class RenderFrameHostDelegate;
+class RenderFrameHostImpl;
 class RenderFrameHostManagerTest;
 class RenderFrameProxyHost;
 class RenderViewHost;
@@ -147,6 +148,12 @@
     virtual NavigationControllerImpl&
         GetControllerForRenderManager() = 0;
 
+    // Creates a WebUI object for the given URL if one applies. Ownership of the
+    // returned pointer will be passed to the caller. If no WebUI applies,
+    // returns NULL.
+    virtual scoped_ptr<WebUIImpl> CreateWebUIForRenderManager(
+        const GURL& url) = 0;
+
     // Returns the navigation entry of the current navigation, or NULL if there
     // is none.
     virtual NavigationEntry*
@@ -242,7 +249,7 @@
   // somehwere else.
   void RemoveOuterDelegateFrame();
 
-  // Returns the pending RenderFrameHost, or null if there is no pending one.
+  // Returns the pending RenderFrameHost, or NULL if there is no pending one.
   RenderFrameHostImpl* pending_frame_host() const {
     return pending_render_frame_host_.get();
   }
@@ -256,12 +263,21 @@
   // TODO(creis): Remove this when we no longer use RVH for navigation.
   RenderViewHostImpl* pending_render_view_host() const;
 
-  // Returns the current committed WebUI or null if none applies.
-  WebUIImpl* web_ui() const { return render_frame_host_->web_ui(); }
+  // Returns the current committed Web UI or NULL if none applies.
+  WebUIImpl* web_ui() const { return web_ui_.get(); }
 
-  // Returns the WebUI associated with the RenderFrameHost that is currently
-  // navigating or null if none applies.
-  WebUIImpl* GetNavigatingWebUI() const;
+  // Returns the Web UI for the pending navigation, or NULL of none applies.
+  WebUIImpl* pending_web_ui() const {
+    return pending_web_ui_.get() ? pending_web_ui_.get() :
+                                   pending_and_current_web_ui_.get();
+  }
+
+  // PlzNavigate
+  // Returns the speculative WebUI for the navigation (a newly created one or
+  // the current one if it should be reused). If none is set returns nullptr.
+  WebUIImpl* speculative_web_ui() const {
+    return should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
+  }
 
   // Called when we want to instruct the renderer to navigate to the given
   // navigation entry. It may create a new RenderFrameHost or re-use an existing
@@ -337,12 +353,19 @@
   void DidChangeOpener(int opener_routing_id,
                        SiteInstance* source_site_instance);
 
-  // Creates and initializes a RenderFrameHost. If |flags| has the
+  // Sets the pending Web UI for the pending navigation, ensuring that the
+  // bindings are appropriate compared to |bindings|.
+  void SetPendingWebUI(const GURL& url, int bindings);
+
+  // Creates and initializes a RenderFrameHost. The |web_ui| is an optional
+  // input parameter used to double check bindings when swapping back in a
+  // previously existing RenderFrameHost. If |flags| has the
   // CREATE_RF_SWAPPED_OUT bit set from the CreateRenderFrameFlags enum, it will
   // initially be placed on the swapped out hosts list. If |view_routing_id_ptr|
   // is not nullptr it will be set to the routing id of the view associated with
   // the frame.
   scoped_ptr<RenderFrameHostImpl> CreateRenderFrame(SiteInstance* instance,
+                                                    WebUIImpl* web_ui,
                                                     int flags,
                                                     int* view_routing_id_ptr);
 
@@ -545,6 +568,16 @@
       const GURL& new_effective_url,
       bool new_is_view_source_mode) const;
 
+  // Creates a new Web UI, ensuring that the bindings are appropriate compared
+  // to |bindings|.
+  scoped_ptr<WebUIImpl> CreateWebUI(const GURL& url, int bindings);
+
+  // Returns true if it is safe to reuse the current WebUI when navigating from
+  // |current_entry| to |new_url|.
+  bool ShouldReuseWebUI(
+      const NavigationEntry* current_entry,
+      const GURL& new_url) const;
+
   // Returns the SiteInstance to use for the navigation.
   SiteInstance* GetSiteInstanceForNavigation(const GURL& dest_url,
                                              SiteInstance* source_instance,
@@ -631,11 +664,13 @@
                                                         int flags);
 
   // PlzNavigate
-  // Create and initialize a speculative RenderFrameHost for an ongoing
-  // navigation. It might be destroyed and re-created later if the navigation
-  // is redirected to a different SiteInstance.
-  bool CreateSpeculativeRenderFrameHost(SiteInstance* old_instance,
-                                        SiteInstance* new_instance);
+  // Creates and initializes a speculative RenderFrameHost and/or WebUI for an
+  // ongoing navigation. They might be destroyed and re-created later if the
+  // navigation is redirected to a different SiteInstance.
+  bool CreateSpeculativeRenderFrameHost(const GURL& url,
+                                        SiteInstance* old_instance,
+                                        SiteInstance* new_instance,
+                                        int bindings);
 
   // Sets up the necessary state for a new RenderViewHost.  If |proxy| is not
   // null, it creates a RenderFrameProxy in the target renderer process which is
@@ -648,8 +683,9 @@
   // above.
   bool InitRenderFrame(RenderFrameHostImpl* render_frame_host);
 
-  // Sets the pending RenderFrameHost to be the active one. Call this for every
-  // commit.
+  // Sets the pending RenderFrameHost/WebUI to be the active one. Note that this
+  // doesn't require the pending render_frame_host_ pointer to be non-NULL,
+  // since there could be Web UI switching as well. Call this for every commit.
   // If PlzNavigate is enabled the method will set the speculative (not pending)
   // RenderFrameHost to be the active one.
   void CommitPending();
@@ -705,22 +741,10 @@
       const GlobalRequestID& transferred_request_id,
       int bindings);
 
-  // Updates the WebUI of the current RenderFrameHost for same-site navigations.
-  void UpdateWebUIOnCurrentFrameHost(const GURL& dest_url,
-                                     bool dest_is_restore,
-                                     int bindings);
-
   // Called when a renderer process is starting to close.  We should not
   // schedule new navigations in its swapped out RenderFrameHosts after this.
   void RendererProcessClosing(RenderProcessHost* render_process_host);
 
-  // Checks that the current navigation case justifies a WebUI change in the
-  // current RenderFrameHost. Will crash the browser if the transition is
-  // considered not acceptable.
-  void CheckWebUITransition(WebUI::TypeID previous_web_ui_type,
-                            const GURL& dest_url,
-                            bool dest_is_restore);
-
   // For use in creating RenderFrameHosts.
   FrameTreeNode* frame_tree_node_;
 
@@ -733,15 +757,25 @@
   RenderViewHostDelegate* render_view_delegate_;
   RenderWidgetHostDelegate* render_widget_delegate_;
 
-  // Our RenderFrameHost which is responsible for all communication with a child
-  // RenderFrame instance.
+  // Our RenderFrameHost and its associated Web UI (if any, will be NULL for
+  // non-WebUI pages). This object is responsible for all communication with
+  // a child RenderFrame instance.
   // For now, RenderFrameHost keeps a RenderViewHost in its SiteInstance alive.
   // Eventually, RenderViewHost will be replaced with a page context.
   scoped_ptr<RenderFrameHostImpl> render_frame_host_;
+  scoped_ptr<WebUIImpl> web_ui_;
 
   // A RenderFrameHost used to load a cross-site page. This remains hidden
-  // while a cross-site request is pending until it calls DidNavigate.
-  // Note: This member is not used in PlzNavigate.
+  // while a cross-site request is pending until it calls DidNavigate. It may
+  // have an associated Web UI, in which case the Web UI pointer will be non-
+  // NULL.
+  //
+  // The |pending_web_ui_| may be non-NULL even when the
+  // |pending_render_frame_host_| is NULL. This will happen when we're
+  // transitioning between two Web UI pages: the RFH won't be swapped, so the
+  // pending pointer will be unused, but there will be a pending Web UI
+  // associated with the navigation.
+  // Note: This is not used in PlzNavigate.
   scoped_ptr<RenderFrameHostImpl> pending_render_frame_host_;
 
   // If a pending request needs to be transferred to another process, this
@@ -757,6 +791,14 @@
   // navigations in PlzNavigate.
   scoped_ptr<NavigationHandleImpl> transfer_navigation_handle_;
 
+  // If either of these is non-NULL, the pending navigation is to a chrome:
+  // page. The scoped_ptr is used if pending_web_ui_ != web_ui_, the WeakPtr is
+  // used for when they reference the same object. If either is non-NULL, the
+  // other should be NULL.
+  // Note: These are not used in PlzNavigate.
+  scoped_ptr<WebUIImpl> pending_web_ui_;
+  base::WeakPtr<WebUIImpl> pending_and_current_web_ui_;
+
   class RenderFrameProxyHostMap;
   scoped_ptr<RenderFrameProxyHostMap> proxy_hosts_;
 
@@ -771,19 +813,21 @@
   InterstitialPageImpl* interstitial_page_;
 
   // PlzNavigate
-  // Stores a speculative RenderFrameHost which is created early in a navigation
-  // so a renderer process can be started in parallel, if needed.
-  // This is purely a performance optimization and is not required for correct
-  // behavior. The speculative RenderFrameHost might be discarded later on if
-  // the final URL's SiteInstance isn't compatible with the one used to create
-  // it.
-  // Note: PlzNavigate only uses the speculative RenderFrameHost, not the
-  // pending one.
+  // These members store a speculative RenderFrameHost and WebUI. They are
+  // created early in a navigation so a renderer process can be started in
+  // parallel, if needed. This is purely a performance optimization and is not
+  // required for correct behavior. The created RenderFrameHost might be
+  // discarded later on if the final URL's SiteInstance isn't compatible with
+  // what was used to create it.
+  // Note: PlzNavigate only uses speculative RenderFrameHost and WebUI, not
+  // the pending ones.
   scoped_ptr<RenderFrameHostImpl> speculative_render_frame_host_;
+  scoped_ptr<WebUIImpl> speculative_web_ui_;
 
-  // Indicates that the WebUI from the current RenderFrameHost is being used for
-  // an ongoing navigation and will be kept at navigation commit time.
-  bool current_web_ui_is_navigating_;
+  // PlzNavigate
+  // If true at navigation commit time the current WebUI will be kept instead of
+  // creating a new one.
+  bool should_reuse_web_ui_;
 
   base::WeakPtrFactory<RenderFrameHostManager> weak_factory_;
 
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
index 5e7ac64..d06b2ff 100644
--- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -1546,16 +1546,14 @@
       shell()->web_contents());
   WebUIImpl* webui = web_contents->GetRenderManagerForTesting()->web_ui();
   EXPECT_TRUE(webui);
-  EXPECT_FALSE(
-      web_contents->GetRenderManagerForTesting()->GetNavigatingWebUI());
+  EXPECT_FALSE(web_contents->GetRenderManagerForTesting()->pending_web_ui());
 
   // Navigate to another WebUI URL that reuses the WebUI object.  Make sure we
-  // clear GetNavigatingWebUI() when it commits.
+  // clear pending_web_ui() when it commits.
   GURL webui_url2(webui_url.spec() + "#foo");
   NavigateToURL(shell(), webui_url2);
   EXPECT_EQ(webui, web_contents->GetRenderManagerForTesting()->web_ui());
-  EXPECT_FALSE(
-      web_contents->GetRenderManagerForTesting()->GetNavigatingWebUI());
+  EXPECT_FALSE(web_contents->GetRenderManagerForTesting()->pending_web_ui());
 }
 
 class RFHMProcessPerTabTest : public RenderFrameHostManagerTest {
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 47530a8..e1d2b5b 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -81,21 +81,13 @@
   // WebUIFactory implementation.
   WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
                                                const GURL& url) const override {
-    // If WebUI creation is enabled for the test and this is a WebUI URL,
-    // returns a new instance.
-    if (should_create_webui_ && HasWebUIScheme(url))
-      return new WebUIController(web_ui);
-    return nullptr;
+    if (!(should_create_webui_ && HasWebUIScheme(url)))
+      return NULL;
+    return new WebUIController(web_ui);
   }
 
   WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
                              const GURL& url) const override {
-    // If WebUI creation is enabled for the test and this is a WebUI URL,
-    // returns a mock WebUI type.
-    if (should_create_webui_ && HasWebUIScheme(url)) {
-      return const_cast<RenderFrameHostManagerTestWebUIControllerFactory*>(
-          this);
-    }
     return WebUI::kNoWebUI;
   }
 
@@ -1124,7 +1116,12 @@
 
   // The Web UI is committed immediately because the RenderViewHost has not been
   // used yet. UpdateStateForNavigate() took the short cut path.
-  EXPECT_FALSE(manager->GetNavigatingWebUI());
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableBrowserSideNavigation)) {
+    EXPECT_FALSE(manager->speculative_web_ui());
+  } else {
+    EXPECT_FALSE(manager->pending_web_ui());
+  }
   EXPECT_TRUE(manager->web_ui());
 
   // Commit.
@@ -1194,7 +1191,12 @@
   // No cross-process transition happens because we are already in the right
   // SiteInstance.  We should grant bindings immediately.
   EXPECT_EQ(host2, manager2->current_frame_host());
-  EXPECT_TRUE(manager2->GetNavigatingWebUI());
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableBrowserSideNavigation)) {
+    EXPECT_TRUE(manager2->speculative_web_ui());
+  } else {
+    EXPECT_TRUE(manager2->pending_web_ui());
+  }
   EXPECT_TRUE(
       host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI);
 
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
index a7b4f93..51966748 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
@@ -94,6 +94,33 @@
     CloseFileDescriptorIfValid(pad_state_[i].device_fd);
 }
 
+void GamepadPlatformDataFetcherLinux::SanitizeGamepadData(size_t index,
+                                                          WebGamepad* pad) {
+  bool* axes_reset = pad_state_[index].is_axes_ever_reset;
+  bool* buttons_reset = pad_state_[index].is_buttons_ever_reset;
+
+  for (size_t axis = 0; axis < pad->axesLength; ++axis) {
+    if (!axes_reset[axis]) {
+      if (fabs(pad->axes[axis]) < kMinAxisResetValue) {
+        axes_reset[axis] = true;
+      } else {
+        pad->axes[axis] = 0.0f;
+      }
+    }
+  }
+
+  for (size_t button = 0; button < pad->buttonsLength; ++button) {
+    if (!buttons_reset[button]) {
+      if (!pad->buttons[button].pressed) {
+        buttons_reset[button] = true;
+      } else {
+        pad->buttons[button].pressed = false;
+        pad->buttons[button].value = 0.0f;
+      }
+    }
+  }
+}
+
 void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) {
   TRACE_EVENT0("GAMEPAD", "GetGamepadData");
 
@@ -112,6 +139,7 @@
       pad_state_[i].mapper(pad_state_[i].data, &pads->items[i]);
     else
       pads->items[i] = pad_state_[i].data;
+    SanitizeGamepadData(i, &pads->items[i]);
   }
 }
 
@@ -255,8 +283,6 @@
 
   const int& fd = pad_state_[index].device_fd;
   WebGamepad& pad = pad_state_[index].data;
-  bool* axes_reset = pad_state_[index].is_axes_ever_reset;
-  bool* buttons_reset = pad_state_[index].is_buttons_ever_reset;
   DCHECK_GE(fd, 0);
 
   js_event event;
@@ -266,14 +292,7 @@
       if (item >= WebGamepad::axesLengthCap)
         continue;
 
-      float val = event.value / kMaxLinuxAxisValue;
-      if (fabs(val) < kMinAxisResetValue)
-        axes_reset[item] = true;
-
-      if (axes_reset[item])
-        pad.axes[item] = val;
-      else
-        pad.axes[item] = 0.0;
+      pad.axes[item] = event.value / kMaxLinuxAxisValue;
 
       if (item >= pad.axesLength)
         pad.axesLength = item + 1;
@@ -281,16 +300,8 @@
       if (item >= WebGamepad::buttonsLengthCap)
         continue;
 
-      if (!event.value)
-        buttons_reset[item] = true;
-
-      if (buttons_reset[item]) {
-        pad.buttons[item].pressed = event.value;
-        pad.buttons[item].value = event.value ? 1.0 : 0.0;
-      } else {
-        pad.buttons[item].pressed = false;
-        pad.buttons[item].value = 0.0;
-      }
+      pad.buttons[item].pressed = event.value;
+      pad.buttons[item].value = event.value ? 1.0 : 0.0;
 
       if (item >= pad.buttonsLength)
         pad.buttonsLength = item + 1;
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h
index 3742d60c..251b3a1 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.h
@@ -35,6 +35,7 @@
   void RefreshDevice(udev_device* dev);
   void EnumerateDevices();
   void ReadDeviceData(size_t index);
+  void SanitizeGamepadData(size_t index, blink::WebGamepad* pad);
 
   struct PadState {
     // File descriptor for the /dev/input/js* devices. -1 if not in use.
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
index 15de8d1c..302a6c1 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.h
@@ -72,6 +72,8 @@
   void RegisterForNotifications();
   void UnregisterFromNotifications();
 
+  void SanitizeGamepadData(size_t index, blink::WebGamepad* pad);
+
   scoped_ptr<XboxDataFetcher> xbox_fetcher_;
 
   blink::WebGamepads data_;
@@ -96,6 +98,8 @@
         UInt32 location_id;
       } xbox;
     };
+    bool is_axes_ever_reset[blink::WebGamepad::axesLengthCap];
+    bool is_buttons_ever_reset[blink::WebGamepad::buttonsLengthCap];
   };
   AssociatedData associated_[blink::WebGamepads::itemsLengthCap];
 
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
index f25d15a..5c276314 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_mac.mm
@@ -50,6 +50,8 @@
 const uint32_t kMultiAxisUsageNumber = 0x08;
 const uint32_t kAxisMinimumUsageNumber = 0x30;
 
+const float kMinAxisResetValue = 0.1;
+
 }  // namespace
 
 GamepadPlatformDataFetcherMac::GamepadPlatformDataFetcherMac()
@@ -328,6 +330,11 @@
   data_.items[slot].connected = true;
   if (slot >= data_.length)
     data_.length = slot + 1;
+
+  for (size_t j = 0; j < blink::WebGamepad::axesLengthCap; ++j)
+    associated_[slot].is_axes_ever_reset[j] = false;
+  for (size_t j = 0; j < blink::WebGamepad::buttonsLengthCap; ++j)
+    associated_[slot].is_buttons_ever_reset[j] = false;
 }
 
 void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) {
@@ -437,6 +444,11 @@
   data_.items[slot].timestamp = 0;
   if (slot >= data_.length)
     data_.length = slot + 1;
+
+  for (size_t j = 0; j < blink::WebGamepad::axesLengthCap; ++j)
+    associated_[slot].is_axes_ever_reset[j] = false;
+  for (size_t j = 0; j < blink::WebGamepad::buttonsLengthCap; ++j)
+    associated_[slot].is_buttons_ever_reset[j] = false;
 }
 
 void GamepadPlatformDataFetcherMac::XboxDeviceRemove(XboxController* device) {
@@ -491,6 +503,33 @@
   pad.timestamp = base::TimeTicks::Now().ToInternalValue();
 }
 
+void GamepadPlatformDataFetcherMac::SanitizeGamepadData(size_t index,
+                                                        WebGamepad* pad) {
+  bool* axes_reset = associated_[index].is_axes_ever_reset;
+  bool* buttons_reset = associated_[index].is_buttons_ever_reset;
+
+  for (size_t axis = 0; axis < pad->axesLength; ++axis) {
+    if (!axes_reset[axis]) {
+      if (fabs(pad->axes[axis]) < kMinAxisResetValue) {
+        axes_reset[axis] = true;
+      } else {
+        pad->axes[axis] = 0.0f;
+      }
+    }
+  }
+
+  for (size_t button = 0; button < pad->buttonsLength; ++button) {
+    if (!buttons_reset[button]) {
+      if (!pad->buttons[button].pressed) {
+        buttons_reset[button] = true;
+      } else {
+        pad->buttons[button].pressed = false;
+        pad->buttons[button].value = 0.0f;
+      }
+    }
+  }
+}
+
 void GamepadPlatformDataFetcherMac::GetGamepadData(WebGamepads* pads, bool) {
   if (!enabled_ && !xbox_fetcher_) {
     pads->length = 0;
@@ -505,6 +544,8 @@
       associated_[i].hid.mapper(data_.items[i], &pads->items[i]);
     else
       pads->items[i] = data_.items[i];
+
+    SanitizeGamepadData(i, &pads->items[i]);
   }
 }
 
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc b/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc
index 88aa7ec0..7372126 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc
@@ -172,6 +172,32 @@
   }
 }
 
+void GamepadPlatformDataFetcherWin::SanitizeGamepadData(size_t index,
+                                                        WebGamepad* pad) {
+  bool* axes_reset = pad_state_[index].is_axes_ever_reset;
+  bool* buttons_reset = pad_state_[index].is_buttons_ever_reset;
+
+  for (size_t axis = 0; axis < pad->axesLength; ++axis) {
+    if (!axes_reset[axis]) {
+      if (fabs(pad->axes[axis]) < kMinAxisResetValue) {
+        axes_reset[axis] = true;
+      } else {
+        pad->axes[axis] = 0.0f;
+      }
+    }
+  }
+
+  for (size_t button = 0; button < pad->buttonsLength; ++button) {
+    if (!buttons_reset[button]) {
+      if (!pad->buttons[button].pressed) {
+        buttons_reset[button] = true;
+      } else {
+        pad->buttons[button].pressed = false;
+        pad->buttons[button].value = 0.0f;
+      }
+    }
+  }
+}
 
 void GamepadPlatformDataFetcherWin::GetGamepadData(WebGamepads* pads,
                                                    bool devices_changed_hint) {
@@ -207,6 +233,8 @@
     else if (pad_state_[i].status == RAWINPUT_CONNECTED)
       GetRawInputPadData(i, &pads->items[i]);
 
+    SanitizeGamepadData(i, &pads->items[i]);
+
     if (pads->items[i].connected)
       pads->length++;
   }
@@ -254,43 +282,25 @@
     pad->buttonsLength = 0;
     WORD val = state.Gamepad.wButtons;
 #define ADD(b) if (!val) \
-    pad_state_[i].is_buttons_ever_reset[pad->buttonsLength] = true; \
-  if (pad_state_[i].is_buttons_ever_reset[pad->buttonsLength]) { \
-    pad->buttons[pad->buttonsLength].pressed = (val & (b)) != 0; \
-    pad->buttons[pad->buttonsLength++].value = ((val & (b)) ? 1.f : 0.f); \
-  } else { \
-    pad->buttons[pad->buttonsLength].pressed = false; \
-    pad->buttons[pad->buttonsLength++].value = 0.0; \
-  }
+  pad->buttons[pad->buttonsLength].pressed = (val & (b)) != 0; \
+  pad->buttons[pad->buttonsLength++].value = ((val & (b)) ? 1.f : 0.f);
     ADD(XINPUT_GAMEPAD_A);
     ADD(XINPUT_GAMEPAD_B);
     ADD(XINPUT_GAMEPAD_X);
     ADD(XINPUT_GAMEPAD_Y);
     ADD(XINPUT_GAMEPAD_LEFT_SHOULDER);
     ADD(XINPUT_GAMEPAD_RIGHT_SHOULDER);
-    if (state.Gamepad.bLeftTrigger < XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
-      pad_state_[i].is_buttons_ever_reset[pad->buttonsLength] = true;
-    if (pad_state_[i].is_buttons_ever_reset[pad->buttonsLength]) {
-      pad->buttons[pad->buttonsLength].pressed =
-        state.Gamepad.bLeftTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
-      pad->buttons[pad->buttonsLength++].value =
-        state.Gamepad.bLeftTrigger / 255.f;
-    } else {
-      pad->buttons[pad->buttonsLength].pressed = false;
-      pad->buttons[pad->buttonsLength++].value = 0.0;
-    }
 
-    if (state.Gamepad.bRightTrigger < XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
-      pad_state_[i].is_buttons_ever_reset[pad->buttonsLength] = true;
-    if (pad_state_[i].is_buttons_ever_reset[pad->buttonsLength]) {
-      pad->buttons[pad->buttonsLength].pressed =
-        state.Gamepad.bRightTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
-      pad->buttons[pad->buttonsLength++].value =
-        state.Gamepad.bRightTrigger / 255.f;
-    } else {
-      pad->buttons[pad->buttonsLength].pressed = false;
-      pad->buttons[pad->buttonsLength++].value = 0.0;
-    }
+    pad->buttons[pad->buttonsLength].pressed =
+      state.Gamepad.bLeftTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
+    pad->buttons[pad->buttonsLength++].value =
+      state.Gamepad.bLeftTrigger / 255.f;
+
+    pad->buttons[pad->buttonsLength].pressed =
+      state.Gamepad.bRightTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
+    pad->buttons[pad->buttonsLength++].value =
+      state.Gamepad.bRightTrigger / 255.f;
+
     ADD(XINPUT_GAMEPAD_BACK);
     ADD(XINPUT_GAMEPAD_START);
     ADD(XINPUT_GAMEPAD_LEFT_THUMB);
@@ -304,12 +314,7 @@
 
     float value = 0.0;
 #define ADD(a, factor) value = factor * NormalizeXInputAxis(a); \
-  if (fabs(value) < kMinAxisResetValue) \
-    pad_state_[i].is_axes_ever_reset[pad->axesLength] = true; \
-  if (pad_state_[i].is_axes_ever_reset[pad->axesLength]) \
-    pad->axes[pad->axesLength++] = value; \
-  else \
-    pad->axes[pad->axesLength++] = 0.0;
+  pad->axes[pad->axesLength++] = value;
 
     // XInput are +up/+right, -down/-left, we want -up/-left.
     ADD(state.Gamepad.sThumbLX, 1);
@@ -339,27 +344,12 @@
   raw_pad.axesLength =  gamepad->axes_length;
 
   for (unsigned int i = 0; i < raw_pad.buttonsLength; i++) {
-    if (!gamepad->buttons[i])
-      pad_state_[index].is_buttons_ever_reset[i] = true;
-
-    if (pad_state_[index].is_buttons_ever_reset[i]) {
-      raw_pad.buttons[i].pressed = gamepad->buttons[i];
-      raw_pad.buttons[i].value = gamepad->buttons[i] ? 1.0 : 0.0;
-    } else {
-      raw_pad.buttons[i].pressed = false;
-      raw_pad.buttons[i].value = 0.0;
-    }
+    raw_pad.buttons[i].pressed = gamepad->buttons[i];
+    raw_pad.buttons[i].value = gamepad->buttons[i] ? 1.0 : 0.0;
   }
 
-  for (unsigned int i = 0; i < raw_pad.axesLength; i++) {
-    if (fabs(gamepad->axes[i].value) < kMinAxisResetValue)
-      pad_state_[index].is_axes_ever_reset[i] = true;
-
-    if (pad_state_[index].is_axes_ever_reset[i])
-      raw_pad.axes[i] = gamepad->axes[i].value;
-    else
-      raw_pad.axes[i] = 0.0;
-  }
+  for (unsigned int i = 0; i < raw_pad.axesLength; i++)
+    raw_pad.axes[i] = gamepad->axes[i].value;
 
   // Copy to the current state to the output buffer, using the mapping
   // function, if there is one available.
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_win.h b/content/browser/gamepad/gamepad_platform_data_fetcher_win.h
index 86ea629..a668366d 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_win.h
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_win.h
@@ -65,6 +65,7 @@
   int FirstAvailableGamepadId() const;
   bool HasXInputGamepad(int index) const;
   bool HasRawInputGamepad(const HANDLE handle) const;
+  void SanitizeGamepadData(size_t index, blink::WebGamepad* pad);
 
   base::ScopedNativeLibrary xinput_dll_;
   bool xinput_available_;
diff --git a/content/browser/quota/quota_database_unittest.cc b/content/browser/quota/quota_database_unittest.cc
index 4bfdd8b..8365e64 100644
--- a/content/browser/quota/quota_database_unittest.cc
+++ b/content/browser/quota/quota_database_unittest.cc
@@ -306,8 +306,8 @@
     const GURL kOrigin3("http://c/");
 
     base::Time last_eviction_time;
-    EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary,
-                                             &last_eviction_time));
+    EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary,
+                                              &last_eviction_time));
     EXPECT_EQ(base::Time(), last_eviction_time);
 
     // Report last eviction time for the test origins.
@@ -337,14 +337,14 @@
         db.DeleteOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary));
 
     last_eviction_time = base::Time();
-    EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary,
-                                             &last_eviction_time));
+    EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary,
+                                              &last_eviction_time));
     EXPECT_EQ(base::Time(), last_eviction_time);
-    EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin2, kStorageTypeTemporary,
-                                             &last_eviction_time));
+    EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin2, kStorageTypeTemporary,
+                                              &last_eviction_time));
     EXPECT_EQ(base::Time(), last_eviction_time);
-    EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary,
-                                             &last_eviction_time));
+    EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary,
+                                              &last_eviction_time));
     EXPECT_EQ(base::Time(), last_eviction_time);
 
     // Deleting an origin that is not present should not fail.
@@ -445,6 +445,36 @@
     EXPECT_TRUE(verifier.table.empty());
   }
 
+  void GetOriginInfo(const base::FilePath& kDbFile) {
+    const GURL kOrigin = GURL("http://go/");
+    typedef QuotaDatabase::OriginInfoTableEntry Entry;
+    Entry kTableEntries[] = {
+        Entry(kOrigin, kStorageTypeTemporary, 100, base::Time(), base::Time())};
+    Entry* begin = kTableEntries;
+    Entry* end = kTableEntries + arraysize(kTableEntries);
+
+    QuotaDatabase db(kDbFile);
+    EXPECT_TRUE(db.LazyOpen(true));
+    AssignOriginInfoTable(db.db_.get(), begin, end);
+    db.Commit();
+
+    {
+      Entry entry;
+      EXPECT_TRUE(db.GetOriginInfo(kOrigin, kStorageTypeTemporary, &entry));
+      EXPECT_EQ(kTableEntries[0].type, entry.type);
+      EXPECT_EQ(kTableEntries[0].origin, entry.origin);
+      EXPECT_EQ(kTableEntries[0].used_count, entry.used_count);
+      EXPECT_EQ(kTableEntries[0].last_access_time, entry.last_access_time);
+      EXPECT_EQ(kTableEntries[0].last_modified_time, entry.last_modified_time);
+    }
+
+    {
+      Entry entry;
+      EXPECT_FALSE(db.GetOriginInfo(GURL("http://notpresent.org/"),
+                                    kStorageTypeTemporary, &entry));
+    }
+  }
+
  private:
   template <typename Iterator>
   void AssignQuotaTable(sql::Connection* db, Iterator itr, Iterator end) {
@@ -645,6 +675,10 @@
   DumpOriginInfoTable(base::FilePath());
 }
 
+TEST_F(QuotaDatabaseTest, GetOriginInfo) {
+  GetOriginInfo(base::FilePath());
+}
+
 TEST_F(QuotaDatabaseTest, OpenCorruptedDatabase) {
   base::ScopedTempDir data_dir;
   ASSERT_TRUE(data_dir.CreateUniqueTempDir());
diff --git a/content/browser/quota/quota_manager_unittest.cc b/content/browser/quota/quota_manager_unittest.cc
index 6a7d1d9b..a2b3a42 100644
--- a/content/browser/quota/quota_manager_unittest.cc
+++ b/content/browser/quota/quota_manager_unittest.cc
@@ -1361,7 +1361,7 @@
 }
 
 TEST_F(QuotaManagerTest, EvictOriginDataHistogram) {
-  const GURL kOrigin = GURL("http://foo.com");
+  const GURL kOrigin = GURL("http://foo.com/");
   static const MockOriginData kData[] = {
       {"http://foo.com/", kTemp, 1},
   };
@@ -1374,31 +1374,52 @@
   GetGlobalUsage(kTemp);
   base::RunLoop().RunUntilIdle();
 
-  EvictOriginData(GURL("http://foo.com/"), kTemp);
+  EvictOriginData(kOrigin, kTemp);
   base::RunLoop().RunUntilIdle();
 
+  // Ensure used count and time since access are recorded.
+  histograms.ExpectTotalCount(
+      QuotaManager::kEvictedOriginAccessedCountHistogram, 1);
+  histograms.ExpectBucketCount(
+      QuotaManager::kEvictedOriginAccessedCountHistogram, 0, 1);
+  histograms.ExpectTotalCount(
+      QuotaManager::kEvictedOriginTimeSinceAccessHistogram, 1);
+
   // First eviction has no 'last' time to compare to.
   histograms.ExpectTotalCount(
       QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, 0);
 
-  client->AddOriginAndNotify(GURL("http://foo.com"), kTemp, 100);
+  client->AddOriginAndNotify(kOrigin, kTemp, 100);
+
+  // Change the used count of the origin.
+  quota_manager()->NotifyStorageAccessed(QuotaClient::kUnknown, GURL(kOrigin),
+                                         kTemp);
+  base::RunLoop().RunUntilIdle();
 
   GetGlobalUsage(kTemp);
   base::RunLoop().RunUntilIdle();
 
-  EvictOriginData(GURL("http://foo.com/"), kTemp);
+  EvictOriginData(kOrigin, kTemp);
   base::RunLoop().RunUntilIdle();
 
-  // Second eviction should log a histogram sample.
+  // The new used count should be logged.
+  histograms.ExpectTotalCount(
+      QuotaManager::kEvictedOriginAccessedCountHistogram, 2);
+  histograms.ExpectBucketCount(
+      QuotaManager::kEvictedOriginAccessedCountHistogram, 1, 1);
+  histograms.ExpectTotalCount(
+      QuotaManager::kEvictedOriginTimeSinceAccessHistogram, 2);
+
+  // Second eviction should log a 'time between repeated eviction' sample.
   histograms.ExpectTotalCount(
       QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, 1);
 
-  client->AddOriginAndNotify(GURL("http://foo.com"), kTemp, 100);
+  client->AddOriginAndNotify(kOrigin, kTemp, 100);
 
   GetGlobalUsage(kTemp);
   base::RunLoop().RunUntilIdle();
 
-  DeleteOriginFromDatabase(GURL("http://foo.com"), kTemp);
+  DeleteOriginFromDatabase(kOrigin, kTemp);
 
   // Deletion from non-eviction source should not log a histogram sample.
   histograms.ExpectTotalCount(
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
index be8f2b0..2cbc8a1 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
+++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
@@ -9,6 +9,7 @@
 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/render_view_host.h"
+#include "content/public/common/context_menu_params.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/aura/client/screen_position_client.h"
 #include "ui/aura/env.h"
@@ -116,10 +117,10 @@
           base::Bind(&TouchSelectionControllerClientAura::ShowQuickMenu,
                      base::Unretained(this)),
           false),
+      quick_menu_requested_(false),
       touch_down_(false),
       scroll_in_progress_(false),
-      handle_drag_in_progress_(false),
-      insertion_quick_menu_allowed_(true) {
+      handle_drag_in_progress_(false) {
   DCHECK(rwhva_);
 }
 
@@ -152,23 +153,23 @@
   UpdateQuickMenu();
 }
 
-bool TouchSelectionControllerClientAura::IsQuickMenuAllowed() const {
-  if (touch_down_ || scroll_in_progress_ || handle_drag_in_progress_)
-    return false;
-
-  switch (rwhva_->selection_controller()->active_status()) {
-    case ui::TouchSelectionController::INACTIVE:
-      return false;
-    case ui::TouchSelectionController::INSERTION_ACTIVE:
-      return insertion_quick_menu_allowed_;
-    case ui::TouchSelectionController::SELECTION_ACTIVE:
-      return true;
+bool TouchSelectionControllerClientAura::HandleContextMenu(
+    const ContextMenuParams& params) {
+  if (params.source_type == ui::MENU_SOURCE_TOUCH && params.is_editable &&
+      params.selection_text.empty() && IsQuickMenuAvailable()) {
+    quick_menu_requested_ = true;
+    UpdateQuickMenu();
+    return true;
   }
-
-  NOTREACHED();
+  rwhva_->selection_controller()->HideAndDisallowShowingAutomatically();
   return false;
 }
 
+bool TouchSelectionControllerClientAura::IsQuickMenuAvailable() const {
+  return ui::TouchSelectionMenuRunner::GetInstance() &&
+         ui::TouchSelectionMenuRunner::GetInstance()->IsMenuAvailable(this);
+}
+
 void TouchSelectionControllerClientAura::ShowQuickMenu() {
   if (!ui::TouchSelectionMenuRunner::GetInstance())
     return;
@@ -213,8 +214,12 @@
   else
     quick_menu_timer_.Stop();
 
+  bool should_show_menu = quick_menu_requested_ && !touch_down_ &&
+                          !scroll_in_progress_ && !handle_drag_in_progress_ &&
+                          IsQuickMenuAvailable();
+
   // Start timer to show quick menu if necessary.
-  if (IsQuickMenuAllowed()) {
+  if (should_show_menu) {
     if (show_quick_menu_immediately_for_test_)
       ShowQuickMenu();
     else
@@ -260,8 +265,9 @@
     ui::SelectionEventType event) {
   switch (event) {
     case ui::SELECTION_HANDLES_SHOWN:
+      quick_menu_requested_ = true;
+      // Fall through.
     case ui::INSERTION_HANDLE_SHOWN:
-      insertion_quick_menu_allowed_ = false;
       UpdateQuickMenu();
       env_pre_target_handler_.reset(new EnvPreTargetHandler(
           rwhva_->selection_controller(), rwhva_->GetNativeView()));
@@ -269,6 +275,7 @@
     case ui::SELECTION_HANDLES_CLEARED:
     case ui::INSERTION_HANDLE_CLEARED:
       env_pre_target_handler_.reset();
+      quick_menu_requested_ = false;
       UpdateQuickMenu();
       break;
     case ui::SELECTION_HANDLE_DRAG_STARTED:
@@ -283,11 +290,10 @@
       break;
     case ui::SELECTION_HANDLES_MOVED:
     case ui::INSERTION_HANDLE_MOVED:
-      insertion_quick_menu_allowed_ = false;
       UpdateQuickMenu();
       break;
     case ui::INSERTION_HANDLE_TAPPED:
-      insertion_quick_menu_allowed_ = !insertion_quick_menu_allowed_;
+      quick_menu_requested_ = !quick_menu_requested_;
       UpdateQuickMenu();
       break;
     case ui::SELECTION_ESTABLISHED:
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura.h b/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
index 0c2f6fe6..ec9ffd5 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
+++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
@@ -11,6 +11,7 @@
 #include "ui/touch_selection/touch_selection_menu_runner.h"
 
 namespace content {
+struct ContextMenuParams;
 class RenderWidgetHostViewAura;
 
 // An implementation of |TouchSelectionControllerClient| to be used in Aura's
@@ -35,11 +36,20 @@
   void OnScrollStarted();
   void OnScrollCompleted();
 
+  // Gives an opportunity to the client to handle context menu request and show
+  // the quick menu instead, if appropriate. Returns |true| to indicate that no
+  // further handling is needed.
+  // TODO(mohsen): This is to match Chrome on Android behavior. However, it is
+  // better not to send context menu request from the renderer in this case and
+  // instead decide in the client about showing the quick menu in response to
+  // selection events. (http://crbug.com/548245)
+  bool HandleContextMenu(const ContextMenuParams& params);
+
  private:
   friend class TestTouchSelectionControllerClientAura;
   class EnvPreTargetHandler;
 
-  bool IsQuickMenuAllowed() const;
+  bool IsQuickMenuAvailable() const;
   void ShowQuickMenu();
   void UpdateQuickMenu();
 
@@ -62,10 +72,10 @@
   RenderWidgetHostViewAura* rwhva_;
 
   base::Timer quick_menu_timer_;
+  bool quick_menu_requested_;
   bool touch_down_;
   bool scroll_in_progress_;
   bool handle_drag_in_progress_;
-  bool insertion_quick_menu_allowed_;
 
   bool show_quick_menu_immediately_for_test_;
 
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
index 102a560..ac432e9 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -46,6 +46,11 @@
   ~TestTouchSelectionMenuRunner() override {}
 
  private:
+  bool IsMenuAvailable(
+      const ui::TouchSelectionMenuClient* client) const override {
+    return true;
+  }
+
   void OpenMenu(ui::TouchSelectionMenuClient* client,
                 const gfx::Rect& anchor_rect,
                 const gfx::Size& handle_image_size,
@@ -142,6 +147,11 @@
     return false;
   }
 
+  bool EmptyTextfield() {
+    return ExecuteScript(shell()->web_contents()->GetMainFrame(),
+                         "empty_textfield()");
+  }
+
  private:
   void SetUpOnMainThread() override {
     ContentBrowserTest::SetUpOnMainThread();
@@ -252,6 +262,48 @@
   EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
 }
 
+// Tests that tapping in an empty textfield does not bring up the insertion
+// handle.
+IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
+                       EmptyTextfieldInsertionOnTap) {
+  // Set the test page up.
+  ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html"));
+  WebContents* web_contents =
+      static_cast<WebContentsImpl*>(shell()->web_contents());
+  RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
+      web_contents->GetRenderWidgetHostView());
+  TestTouchSelectionControllerClientAura* selection_controller_client =
+      new TestTouchSelectionControllerClientAura(rwhva);
+  rwhva->SetSelectionControllerClientForTest(
+      make_scoped_ptr(selection_controller_client));
+
+  // Clear textfield contents.
+  ASSERT_TRUE(EmptyTextfield());
+
+  EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
+            rwhva->selection_controller()->active_status());
+  EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+
+  // Tap inside the textfield and wait for the insertion cursor.
+  selection_controller_client->InitWaitForSelectionEvent(
+      ui::SELECTION_ESTABLISHED);
+
+  gfx::PointF point;
+  ASSERT_TRUE(GetPointInsideTextfield(&point));
+  ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP);
+  tap_details.set_tap_count(1);
+  ui::GestureEvent tap(point.x(), point.y(), 0, ui::EventTimeForNow(),
+                       tap_details);
+  rwhva->OnGestureEvent(&tap);
+
+  selection_controller_client->Wait();
+
+  // Check that insertion is not active and the quick menu is not showing.
+  EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
+            rwhva->selection_controller()->active_status());
+  EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+}
+
 // Tests that the quick menu is hidden whenever a touch point is active.
 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
                        QuickMenuHiddenOnTouch) {
diff --git a/content/browser/renderer_host/input/web_input_event_builders_android.cc b/content/browser/renderer_host/input/web_input_event_builders_android.cc
index 1d240fab..3fb06bb9 100644
--- a/content/browser/renderer_host/input/web_input_event_builders_android.cc
+++ b/content/browser/renderer_host/input/web_input_event_builders_android.cc
@@ -5,8 +5,8 @@
 #include "content/browser/renderer_host/input/web_input_event_builders_android.h"
 
 #include "base/logging.h"
-#include "content/browser/renderer_host/input/motion_event_android.h"
 #include "content/browser/renderer_host/input/web_input_event_util.h"
+#include "ui/events/android/motion_event_android.h"
 #include "ui/events/keycodes/dom/dom_code.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
 #include "ui/events/keycodes/keyboard_code_conversion.h"
diff --git a/content/browser/renderer_host/input/web_input_event_builders_android.h b/content/browser/renderer_host/input/web_input_event_builders_android.h
index 33d77337..5ade65a3 100644
--- a/content/browser/renderer_host/input/web_input_event_builders_android.h
+++ b/content/browser/renderer_host/input/web_input_event_builders_android.h
@@ -9,9 +9,11 @@
 
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
-namespace content {
-
+namespace ui {
 class MotionEventAndroid;
+}
+
+namespace content {
 
 class WebMouseEventBuilder {
  public:
diff --git a/content/browser/renderer_host/media/audio_sync_reader.cc b/content/browser/renderer_host/media/audio_sync_reader.cc
index 7c493e1c..f6b3d6ce 100644
--- a/content/browser/renderer_host/media/audio_sync_reader.cc
+++ b/content/browser/renderer_host/media/audio_sync_reader.cc
@@ -93,6 +93,12 @@
   ++renderer_callback_count_;
   if (!WaitUntilDataIsReady()) {
     ++renderer_missed_callback_count_;
+    if (renderer_missed_callback_count_ <= 100) {
+      LOG(WARNING) << "AudioSyncReader::Read timed out, audio glitch count="
+                   << renderer_missed_callback_count_;
+      if (renderer_missed_callback_count_ == 100)
+        LOG(WARNING) << "(log cap reached, suppressing further logs)";
+    }
     dest->Zero();
     return;
   }
diff --git a/content/browser/renderer_host/render_widget_host_delegate.cc b/content/browser/renderer_host/render_widget_host_delegate.cc
index 7b8def6..fd9c1cb 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.cc
+++ b/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -47,4 +47,10 @@
   return nullptr;
 }
 
+// If a delegate does not override this, the RenderWidgetHostView will
+// assume its own RenderWidgetHost should consume keyboard events.
+RenderWidgetHostImpl* RenderWidgetHostDelegate::GetFocusedRenderWidgetHost() {
+  return nullptr;
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h
index e9c043e9..aa9b4ff 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -65,9 +65,10 @@
   // the event itself.
   virtual bool HandleWheelEvent(const blink::WebMouseWheelEvent& event);
 
-  // Notification the user has performed a direct interaction (mouse down, raw
-  // key down, or gesture tap) while focus was on the page. This is used to
-  // inform the delegate that a user is interacting with a site.
+  // Notification the user has performed a direct interaction (mouse down, mouse
+  // wheel, raw key down, or gesture tap) while focus was on the page. Informs
+  // the delegate that a user is interacting with a site. Only the first mouse
+  // wheel event during a scroll will trigger this method.
   virtual void OnUserInteraction(const blink::WebInputEvent::Type type) {}
 
   // Callback to give the browser a chance to handle the specified gesture
@@ -105,6 +106,12 @@
   // current FrameTree, not including the main frame's SiteInstance.
   virtual void ReplicatePageFocus(bool is_focused) {}
 
+  // Get the RenderWidgetHost of the currently focused frame.  With
+  // out-of-process iframes, multiple RenderWidgetHosts may be involved in
+  // rendering a page, and this function determines which RenderWidgetHost
+  // should consume a keyboard input event.
+  virtual RenderWidgetHostImpl* GetFocusedRenderWidgetHost();
+
 #if defined(OS_WIN)
   virtual gfx::NativeViewAccessible GetParentNativeViewAccessible();
 #endif
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 0a9f05f..62103fd 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -92,6 +92,13 @@
 namespace content {
 namespace {
 
+// The amount of time after a mouse wheel event is sent to the delegate
+// OnUserInteraction method before another mouse wheel event will be sent. This
+// interval is used by the Blink EventHandler in its orthogonal heuristic for
+// detecting the end of a scroll event (if no event has been seen in 0.1
+// seconds, send an end scroll).
+const double kMouseWheelCoalesceIntervalInSeconds = 0.1;
+
 bool g_check_for_pending_resize_ack = true;
 
 // <process id, routing id>
@@ -204,6 +211,7 @@
           base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
       new_content_rendering_delay_(
           base::TimeDelta::FromMilliseconds(kNewContentRenderingDelayMs)),
+      mouse_wheel_coalesce_timer_(new base::ElapsedTimer()),
       weak_factory_(this) {
   CHECK(delegate_);
   CHECK_NE(MSG_ROUTING_NONE, routing_id_);
@@ -1860,6 +1868,13 @@
         event.type == WebInputEvent::GestureTapDown ||
         event.type == WebInputEvent::RawKeyDown) {
       delegate_->OnUserInteraction(event.type);
+    } else if (event.type == WebInputEvent::MouseWheel) {
+      if (mouse_wheel_coalesce_timer_->Elapsed().InSecondsF() >
+          kMouseWheelCoalesceIntervalInSeconds) {
+        delegate_->OnUserInteraction(event.type);
+      }
+
+      mouse_wheel_coalesce_timer_.reset(new base::ElapsedTimer());
     }
   }
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index ccfeeb9..ef80f9e9 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -18,7 +18,7 @@
 #include "base/process/kill.h"
 #include "base/strings/string16.h"
 #include "base/time/time.h"
-#include "base/timer/timer.h"
+#include "base/timer/elapsed_timer.h"
 #include "build/build_config.h"
 #include "cc/resources/shared_bitmap.h"
 #include "content/browser/renderer_host/event_with_latency_info.h"
@@ -853,6 +853,11 @@
   // renderer process before clearing any previously displayed content.
   base::TimeDelta new_content_rendering_delay_;
 
+  // Timer used to batch together mouse wheel events for the delegate
+  // OnUserInteraction method. A wheel event is only dispatched when a wheel
+  // event has not been seen for kMouseWheelCoalesceInterval seconds prior.
+  scoped_ptr<base::ElapsedTimer> mouse_wheel_coalesce_timer_;
+
   base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl);
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 3dab027d..11c2e74 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1687,8 +1687,21 @@
 
 void RenderWidgetHostViewAndroid::SendKeyEvent(
     const NativeWebKeyboardEvent& event) {
-  if (host_)
-    host_->ForwardKeyboardEvent(event);
+  if (!host_)
+    return;
+
+  RenderWidgetHostImpl* target_host = host_;
+
+  // If there are multiple widgets on the page (such as when there are
+  // out-of-process iframes), pick the one that should process this event.
+  if (host_->delegate()) {
+    RenderWidgetHostImpl* focused_host =
+        host_->delegate()->GetFocusedRenderWidgetHost();
+    if (focused_host)
+      target_host = focused_host;
+  }
+
+  target_host->ForwardKeyboardEvent(event);
 }
 
 void RenderWidgetHostViewAndroid::SendMouseEvent(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index bbb79c9..77ea388 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2738,6 +2738,17 @@
 
 void RenderWidgetHostViewAura::ForwardKeyboardEvent(
     const NativeWebKeyboardEvent& event) {
+  RenderWidgetHostImpl* target_host = host_;
+
+  // If there are multiple widgets on the page (such as when there are
+  // out-of-process iframes), pick the one that should process this event.
+  if (host_->delegate()) {
+    RenderWidgetHostImpl* focused_host =
+        host_->delegate()->GetFocusedRenderWidgetHost();
+    if (focused_host)
+      target_host = focused_host;
+  }
+
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   ui::TextEditKeyBindingsDelegateAuraLinux* keybinding_delegate =
       ui::GetTextEditKeyBindingsDelegate();
@@ -2753,16 +2764,19 @@
       edit_commands.push_back(EditCommand(it->GetCommandString(),
                                           it->argument()));
     }
-    host_->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
-        host_->GetRoutingID(), edit_commands));
+    // TODO(alexmos): This needs to be refactored to work with subframe
+    // RenderWidgetHosts for OOPIF.  See https://crbug.com/549334.
+    target_host->Send(new InputMsg_SetEditCommandsForNextKeyEvent(
+        target_host->GetRoutingID(), edit_commands));
+
     NativeWebKeyboardEvent copy_event(event);
     copy_event.match_edit_command = true;
-    host_->ForwardKeyboardEvent(copy_event);
+    target_host->ForwardKeyboardEvent(event);
     return;
   }
 #endif
 
-  host_->ForwardKeyboardEvent(event);
+  target_host->ForwardKeyboardEvent(event);
 }
 
 void RenderWidgetHostViewAura::SelectionUpdated(bool is_editable,
@@ -2780,7 +2794,7 @@
       ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
   tsc_config.tap_slop = ui::GestureConfiguration::GetInstance()
                             ->max_touch_move_in_pixels_for_click();
-  tsc_config.show_on_tap_for_empty_editable = true;
+  tsc_config.show_on_tap_for_empty_editable = false;
   tsc_config.enable_longpress_drag_selection = false;
   selection_controller_.reset(new ui::TouchSelectionController(
       selection_controller_client_.get(), tsc_config));
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index fb89516..b349033 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -2092,6 +2092,15 @@
     return;
   }
 
+  // If there are multiple widgets on the page (such as when there are
+  // out-of-process iframes), pick the one that should process this event.
+  if (widgetHost->delegate()) {
+    RenderWidgetHostImpl* focusedHost =
+        widgetHost->delegate()->GetFocusedRenderWidgetHost();
+    if (focusedHost)
+      widgetHost = focusedHost;
+  }
+
   // Suppress the escape key up event if necessary.
   if (event.windowsKeyCode == ui::VKEY_ESCAPE && suppressNextEscapeKeyUp_) {
     if (event.type == NativeWebKeyboardEvent::KeyUp)
diff --git a/content/browser/resources/gpu/browser_bridge.js b/content/browser/resources/gpu/browser_bridge.js
index 1cf980f..b835f44 100644
--- a/content/browser/resources/gpu/browser_bridge.js
+++ b/content/browser/resources/gpu/browser_bridge.js
@@ -156,6 +156,17 @@
       return this.logMessages_;
     },
 
+    /**
+     * Returns the value of the "Sandboxed" row.
+     */
+    isSandboxedForTesting : function() {
+      for (i = 0; i < this.gpuInfo_.basic_info.length; ++i) {
+        var info = this.gpuInfo_.basic_info[i];
+        if (info.description == "Sandboxed")
+          return info.value;
+      }
+      return false;
+    }
   };
 
   return {
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 4df5541..582d90a7 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -3911,4 +3911,47 @@
   EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url);
 }
 
+// Ensure that a cross-process subframe can receive keyboard events when in
+// focus.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+                       SubframeKeyboardEventRouting) {
+  GURL main_url(embedded_test_server()->GetURL(
+      "a.com", "/frame_tree/page_with_one_frame.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  WebContentsImpl* web_contents =
+      static_cast<WebContentsImpl*>(shell()->web_contents());
+  FrameTreeNode* root = web_contents->GetFrameTree()->root();
+
+  GURL frame_url(
+      embedded_test_server()->GetURL("b.com", "/page_with_input_field.html"));
+  NavigateFrameToURL(root->child_at(0), frame_url);
+  EXPECT_TRUE(WaitForRenderFrameReady(root->child_at(0)->current_frame_host()));
+
+  // Click on the subframe to focus it.
+  SimulateMouseClick(
+      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);
+
+  // Focus the input field in the subframe.  The return value "input-focus"
+  // will be sent once the input field's focus event fires.
+  std::string result;
+  EXPECT_TRUE(ExecuteScriptAndExtractString(
+      root->child_at(0)->current_frame_host(), "focusInputField()", &result));
+  EXPECT_EQ(result, "input-focus");
+
+  // The subframe should now be focused.
+  EXPECT_EQ(root->child_at(0), root->frame_tree()->GetFocusedFrame());
+
+  // Generate a few keyboard events and route them to currently focused frame.
+  SimulateKeyPress(web_contents, ui::VKEY_F, false, false, false, false);
+  SimulateKeyPress(web_contents, ui::VKEY_O, false, false, false, false);
+  SimulateKeyPress(web_contents, ui::VKEY_O, false, false, false, false);
+
+  // Verify that the input field in the subframe received the keystrokes.
+  EXPECT_TRUE(ExecuteScriptAndExtractString(
+      root->child_at(0)->current_frame_host(),
+      "window.domAutomationController.send(getInputFieldText());", &result));
+  EXPECT_EQ("FOO", result);
+}
+
 }  // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index bf45da94..e979525 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/command_line.h"
+#include "base/debug/crash_logging.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -840,9 +841,8 @@
 }
 
 WebUI* WebContentsImpl::GetWebUI() const {
-  return GetRenderManager()->web_ui()
-             ? GetRenderManager()->web_ui()
-             : GetRenderManager()->GetNavigatingWebUI();
+  return GetRenderManager()->web_ui() ? GetRenderManager()->web_ui()
+      : GetRenderManager()->pending_web_ui();
 }
 
 WebUI* WebContentsImpl::GetCommittedWebUI() const {
@@ -913,9 +913,8 @@
   if (entry) {
     return entry->GetTitleForDisplay(accept_languages);
   }
-  WebUI* our_web_ui = GetRenderManager()->GetNavigatingWebUI()
-                          ? GetRenderManager()->GetNavigatingWebUI()
-                          : GetRenderManager()->web_ui();
+  WebUI* our_web_ui = GetRenderManager()->pending_web_ui() ?
+      GetRenderManager()->pending_web_ui() : GetRenderManager()->web_ui();
   if (our_web_ui) {
     // Don't override the title in view source mode.
     entry = controller_.GetVisibleEntry();
@@ -1588,6 +1587,18 @@
   frame_tree_.ReplicatePageFocus(is_focused);
 }
 
+RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost() {
+  if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
+    return GetMainFrame()->GetRenderWidgetHost();
+
+  FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame();
+  if (!focused_frame)
+    return GetMainFrame()->GetRenderWidgetHost();
+
+  return RenderWidgetHostImpl::From(
+      focused_frame->current_frame_host()->GetView()->GetRenderWidgetHost());
+}
+
 void WebContentsImpl::EnterFullscreenMode(const GURL& origin) {
   // This method is being called to enter renderer-initiated fullscreen mode.
   // Make sure any existing fullscreen widget is shut down first.
@@ -3633,8 +3644,6 @@
 }
 
 void WebContentsImpl::RenderFrameCreated(RenderFrameHost* render_frame_host) {
-  // Note this is only for subframes, the notification for the main frame
-  // happens in RenderViewCreated.
   FOR_EACH_OBSERVER(WebContentsObserver,
                     observers_,
                     RenderFrameCreated(render_frame_host));
@@ -3781,6 +3790,18 @@
       Source<WebContents>(this),
       Details<RenderViewHost>(render_view_host));
 
+  // When we're creating views, we're still doing initial setup, so we always
+  // use the pending Web UI rather than any possibly existing committed one.
+  if (GetRenderManager()->pending_web_ui())
+    GetRenderManager()->pending_web_ui()->RenderViewCreated(render_view_host);
+
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableBrowserSideNavigation) &&
+      GetRenderManager()->speculative_web_ui()) {
+    GetRenderManager()->speculative_web_ui()->RenderViewCreated(
+        render_view_host);
+  }
+
   NavigationEntry* entry = controller_.GetPendingEntry();
   if (entry && entry->IsViewSourceMode()) {
     // Put the renderer in view source mode.
@@ -3878,14 +3899,37 @@
   RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(rvh);
   NavigationEntryImpl* entry = controller_.GetEntryWithPageID(
       rvhi->GetSiteInstance(), page_id);
+
+  int nav_entry_id =
+      static_cast<RenderFrameHostImpl*>(rvhi->GetMainFrame())->nav_entry_id();
+  NavigationEntryImpl* new_entry =
+      controller_.GetEntryWithUniqueID(nav_entry_id);
+
+  base::debug::SetCrashKeyValue("pageid", base::IntToString(page_id));
+  base::debug::SetCrashKeyValue("navuniqueid", base::IntToString(nav_entry_id));
+  base::debug::SetCrashKeyValue(
+      "oldindex", base::IntToString(controller_.GetIndexOfEntry(entry)));
+  base::debug::SetCrashKeyValue(
+      "newindex", base::IntToString(controller_.GetIndexOfEntry(new_entry)));
+  base::debug::SetCrashKeyValue(
+      "lastcommittedindex",
+      base::IntToString(controller_.GetLastCommittedEntryIndex()));
+  base::debug::SetCrashKeyValue("oldurl",
+                                entry ? entry->GetURL().spec() : "-nullptr-");
+  base::debug::SetCrashKeyValue(
+      "newurl", new_entry ? new_entry->GetURL().spec() : "-nullptr-");
+  base::debug::SetCrashKeyValue(
+      "updatedvalue", page_state.GetTopLevelUrlStringTemporaryForBug369661());
+  base::debug::SetCrashKeyValue(
+      "oldvalue", entry ? entry->GetURL().spec() : "-nullptr-");
+  base::debug::SetCrashKeyValue(
+      "newvalue",
+      new_entry ? new_entry->GetURL().spec() : "-nullptr-");
+  CHECK_EQ(entry, new_entry);
+
   if (!entry)
     return;
 
-  NavigationEntryImpl* new_entry = controller_.GetEntryWithUniqueID(
-      static_cast<RenderFrameHostImpl*>(rvhi->GetMainFrame())->nav_entry_id());
-
-  DCHECK_EQ(entry, new_entry);
-
   if (page_state == entry->GetPageState())
     return;  // Nothing to update.
   entry->SetPageState(page_state);
@@ -4087,9 +4131,31 @@
   NavigationEntryImpl* entry = controller_.GetEntryWithPageID(
       render_frame_host->GetSiteInstance(), page_id);
 
-  NavigationEntryImpl* new_entry = controller_.GetEntryWithUniqueID(
-      static_cast<RenderFrameHostImpl*>(render_frame_host)->nav_entry_id());
-  DCHECK_EQ(entry, new_entry);
+  int nav_entry_id =
+      static_cast<RenderFrameHostImpl*>(render_frame_host)->nav_entry_id();
+  NavigationEntryImpl* new_entry =
+      controller_.GetEntryWithUniqueID(nav_entry_id);
+
+  base::debug::SetCrashKeyValue("pageid", base::IntToString(page_id));
+  base::debug::SetCrashKeyValue("navuniqueid", base::IntToString(nav_entry_id));
+  base::debug::SetCrashKeyValue(
+      "oldindex", base::IntToString(controller_.GetIndexOfEntry(entry)));
+  base::debug::SetCrashKeyValue(
+      "newindex", base::IntToString(controller_.GetIndexOfEntry(new_entry)));
+  base::debug::SetCrashKeyValue(
+      "lastcommittedindex",
+      base::IntToString(controller_.GetLastCommittedEntryIndex()));
+  base::debug::SetCrashKeyValue("oldurl",
+                                entry ? entry->GetURL().spec() : "-nullptr-");
+  base::debug::SetCrashKeyValue(
+      "newurl", new_entry ? new_entry->GetURL().spec() : "-nullptr-");
+  base::debug::SetCrashKeyValue("updatedvalue", base::UTF16ToUTF8(title));
+  base::debug::SetCrashKeyValue(
+      "oldvalue", entry ? base::UTF16ToUTF8(entry->GetTitle()) : "-nullptr-");
+  base::debug::SetCrashKeyValue(
+      "newvalue",
+      new_entry ? base::UTF16ToUTF8(new_entry->GetTitle()) : "-nullptr-");
+  CHECK_EQ(entry, new_entry);
 
   // We can handle title updates when we don't have an entry in
   // UpdateTitleForEntry, but only if the update is from the current RVH.
@@ -4189,7 +4255,7 @@
     GetRenderManager()->CreateRenderFrameProxy(instance);
   } else {
     GetRenderManager()->CreateRenderFrame(
-        instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
+        instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
         &render_view_routing_id);
   }
   return render_view_routing_id;
@@ -4356,7 +4422,7 @@
   return GetController();
 }
 
-scoped_ptr<WebUIImpl> WebContentsImpl::CreateWebUIForRenderFrameHost(
+scoped_ptr<WebUIImpl> WebContentsImpl::CreateWebUIForRenderManager(
     const GURL& url) {
   return scoped_ptr<WebUIImpl>(static_cast<WebUIImpl*>(CreateWebUI(
       url, std::string())));
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index ea8095d2..0bd9c5c 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -439,7 +439,6 @@
       RenderFrameHost* target_rfh,
       SiteInstance* source_site_instance) const override;
   void EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) override;
-  scoped_ptr<WebUIImpl> CreateWebUIForRenderFrameHost(const GURL& url) override;
 #if defined(OS_WIN)
   gfx::NativeViewAccessible GetParentNativeViewAccessible() override;
 #endif
@@ -596,6 +595,7 @@
       override;
   RenderWidgetHostInputEventRouter* GetInputEventRouter() override;
   void ReplicatePageFocus(bool is_focused) override;
+  RenderWidgetHostImpl* GetFocusedRenderWidgetHost() override;
 
   // RenderFrameHostManager::Delegate ------------------------------------------
 
@@ -627,6 +627,7 @@
       RenderViewHost* old_host,
       RenderViewHost* new_host) override;
   NavigationControllerImpl& GetControllerForRenderManager() override;
+  scoped_ptr<WebUIImpl> CreateWebUIForRenderManager(const GURL& url) override;
   NavigationEntry* GetLastCommittedNavigationEntryForRenderManager() override;
   bool FocusLocationBarByDefault() override;
   void SetFocusToLocationBar(bool select_all) override;
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index 824dc46..28ee915d 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -944,9 +944,12 @@
 
 void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host,
                                           const ContextMenuParams& params) {
-  ui::TouchSelectionController* selection_controller = GetSelectionController();
-  if (selection_controller)
-    selection_controller->HideAndDisallowShowingAutomatically();
+  TouchSelectionControllerClientAura* selection_controller_client =
+      GetSelectionControllerClient();
+  if (selection_controller_client &&
+      selection_controller_client->HandleContextMenu(params)) {
+    return;
+  }
   if (delegate_) {
     RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
         web_contents_->GetRenderWidgetHostView());
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 7f99386..67c6f8e 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -1074,11 +1074,11 @@
       GetContentClient()->GetLocalizedString(message_id), values, NULL);
 }
 
-double BlinkPlatformImpl::currentTime() {
+double BlinkPlatformImpl::currentTimeSeconds() {
   return base::Time::Now().ToDoubleT();
 }
 
-double BlinkPlatformImpl::monotonicallyIncreasingTime() {
+double BlinkPlatformImpl::monotonicallyIncreasingTimeSeconds() {
   return base::TimeTicks::Now().ToInternalValue() /
       static_cast<double>(base::Time::kMicrosecondsPerSecond);
 }
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index 6e7f834a..6aab04ba 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -165,8 +165,8 @@
       const blink::WebString& value1,
       const blink::WebString& value2) override;
   void suddenTerminationChanged(bool enabled) override {}
-  double currentTime() override;
-  double monotonicallyIncreasingTime() override;
+  double currentTimeSeconds() override;
+  double monotonicallyIncreasingTimeSeconds() override;
   double systemTraceTime() override;
   void cryptographicallyRandomValues(unsigned char* buffer,
                                      size_t length) override;
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc
index 332b6376..f9eae9a 100644
--- a/content/child/resource_dispatcher.cc
+++ b/content/child/resource_dispatcher.cc
@@ -101,6 +101,12 @@
     return true;
   }
 
+  // TODO(erikchen): Temporary debugging for http://crbug.com/550938.
+  if (message.type() == ResourceMsg_SetDataBuffer::ID)
+    request_info->has_received_buffer = true;
+  if (message.type() == ResourceMsg_DataReceived::ID)
+    CHECK(request_info->has_received_buffer);
+
   if (request_info->is_deferred) {
     request_info->deferred_message_queue.push_back(new IPC::Message(message));
     return true;
@@ -192,7 +198,7 @@
 
   request_info->buffer.reset(
       new base::SharedMemory(shm_handle, true));  // read only
-  request_info->has_received_buffer = true;
+  request_info->has_processed_buffer = true;
   request_info->received_data_factory =
       make_scoped_refptr(new SharedMemoryReceivedDataFactory(
           message_sender_, request_id, request_info->buffer));
@@ -226,7 +232,7 @@
   bool send_ack = true;
   if (request_info && data_length > 0) {
     // TODO(erikchen): Temporary debugging. http://crbug.com/550938.
-    CHECK(request_info->has_received_buffer);
+    CHECK(request_info->has_processed_buffer);
     CHECK(!request_info->has_destroyed_buffer);
     CHECK(request_info->buffer.get());
 
@@ -513,6 +519,7 @@
       download_to_file(download_to_file),
       request_start(base::TimeTicks::Now()),
       has_received_buffer(false),
+      has_processed_buffer(false),
       has_destroyed_buffer(false) {
 }
 
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h
index b26a97a..604c636 100644
--- a/content/child/resource_dispatcher.h
+++ b/content/child/resource_dispatcher.h
@@ -176,6 +176,7 @@
 
     // TODO(erikchen): Temporary debugging for http://crbug.com/550938.
     bool has_received_buffer;
+    bool has_processed_buffer;
     bool has_destroyed_buffer;
   };
   typedef base::hash_map<int, PendingRequestInfo> PendingRequestList;
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc
index 3d58c900..1c999e31 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator.cc
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc
@@ -654,27 +654,23 @@
   // Instead of crashing while delay loading the DLL when calling MFStartup()
   // below, probe whether we can successfully load the DLL now.
   // See http://crbug.com/339678 for details.
-  HMODULE dxgi_manager_dll = NULL;
-  if ((dxgi_manager_dll = ::GetModuleHandle(L"MFPlat.dll")) == NULL) {
-    HMODULE mfplat_dll = ::LoadLibrary(L"MFPlat.dll");
-    RETURN_ON_FAILURE(mfplat_dll, "MFPlat.dll is required for decoding",
-                      false);
-    // On Windows 8+ mfplat.dll provides the MFCreateDXGIDeviceManager API.
-    // On Windows 7 mshtmlmedia.dll provides it.
-    dxgi_manager_dll = mfplat_dll;
-  }
+  HMODULE dxgi_manager_dll = ::GetModuleHandle(L"MFPlat.dll");
+  RETURN_ON_FAILURE(dxgi_manager_dll, "MFPlat.dll is required for decoding",
+                    false);
+
+  // On Windows 8+ mfplat.dll provides the MFCreateDXGIDeviceManager API.
+  // On Windows 7 mshtmlmedia.dll provides it.
 
   // TODO(ananta)
   // The code below works, as in we can create the DX11 device manager for
   // Windows 7. However the IMFTransform we use for texture conversion and
   // copy does not exist on Windows 7. Look into an alternate approach
   // and enable the code below.
-#if defined ENABLE_DX11_FOR_WIN7
-  if ((base::win::GetVersion() == base::win::VERSION_WIN7) &&
-       ((dxgi_manager_dll = ::GetModuleHandle(L"mshtmlmedia.dll")) == NULL)) {
-    HMODULE mshtml_media_dll = ::LoadLibrary(L"mshtmlmedia.dll");
-    if (mshtml_media_dll)
-      dxgi_manager_dll = mshtml_media_dll;
+#if defined(ENABLE_DX11_FOR_WIN7)
+  if (base::win::GetVersion() == base::win::VERSION_WIN7) {
+    dxgi_manager_dll = ::GetModuleHandle(L"mshtmlmedia.dll");
+    RETURN_ON_FAILURE(dxgi_manager_dll,
+        "mshtmlmedia.dll is required for decoding", false);
   }
 #endif
   // If we don't find the MFCreateDXGIDeviceManager API we fallback to D3D9
@@ -819,7 +815,7 @@
       d3d11_query_.Receive());
   RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false);
 
-  HMODULE video_processor_dll = ::LoadLibrary(L"msvproc.dll");
+  HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll");
   RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor",
                     false);
 
@@ -1035,6 +1031,21 @@
   return profiles;
 }
 
+// static
+void DXVAVideoDecodeAccelerator::PreSandboxInitialization() {
+  ::LoadLibrary(L"MFPlat.dll");
+  ::LoadLibrary(L"msmpeg2vdec.dll");
+
+  if (base::win::GetVersion() > base::win::VERSION_WIN7) {
+    LoadLibrary(L"msvproc.dll");
+  } else {
+    LoadLibrary(L"dxva2.dll");
+#if defined(ENABLE_DX11_FOR_WIN7)
+    LoadLibrary(L"mshtmlmedia.dll");
+#endif
+  }
+}
+
 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
   HMODULE decoder_dll = NULL;
 
@@ -1046,7 +1057,7 @@
     // was previously done because it failed inside the sandbox, and now is done
     // as a more minimal approach to avoid other side-effects CCI might have (as
     // we are still in a reduced sandbox).
-    decoder_dll = ::LoadLibrary(L"msmpeg2vdec.dll");
+    decoder_dll = ::GetModuleHandle(L"msmpeg2vdec.dll");
     RETURN_ON_FAILURE(decoder_dll,
                       "msmpeg2vdec.dll required for decoding is not loaded",
                       false);
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.h b/content/common/gpu/media/dxva_video_decode_accelerator.h
index 24f84a5..86125ed 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator.h
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.h
@@ -79,6 +79,9 @@
   static media::VideoDecodeAccelerator::SupportedProfiles
       GetSupportedProfiles();
 
+  // Preload dlls required for decoding.
+  static void PreSandboxInitialization();
+
  private:
   typedef void* EGLConfig;
   typedef void* EGLSurface;
diff --git a/content/common/gpu/media/vaapi_wrapper.cc b/content/common/gpu/media/vaapi_wrapper.cc
index b08aa03..4f073d3a 100644
--- a/content/common/gpu/media/vaapi_wrapper.cc
+++ b/content/common/gpu/media/vaapi_wrapper.cc
@@ -974,6 +974,7 @@
   pipeline_param->output_region = &output_region;
   pipeline_param->output_background_color = 0xff000000;
   pipeline_param->output_color_standard = VAProcColorStandardNone;
+  pipeline_param->filter_flags = VA_FILTER_SCALING_HQ;
 
   VA_SUCCESS_OR_RETURN(vaUnmapBuffer(va_display_, va_vpp_buffer_id_),
                        "Couldn't unmap vpp buffer", false);
diff --git a/content/content.gyp b/content/content.gyp
index f1a2a97..cdc758a 100644
--- a/content/content.gyp
+++ b/content/content.gyp
@@ -602,20 +602,10 @@
           'includes': [ '../build/jar_file_jni_generator.gypi' ],
         },
         {
-          'target_name': 'motionevent_jni_headers',
-          'type': 'none',
-          'variables': {
-             'jni_gen_package': 'content',
-             'input_java_class': 'android/view/MotionEvent.class',
-           },
-          'includes': [ '../build/jar_file_jni_generator.gypi' ],
-        },
-        {
           'target_name': 'content_jni_headers',
           'type': 'none',
           'dependencies': [
             'java_set_jni_headers',
-            'motionevent_jni_headers'
           ],
           'includes': [ 'content_jni.gypi' ],
           'conditions': [
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 325e6a7b..6969d21 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -1162,8 +1162,6 @@
       'browser/renderer_host/input/input_router_config_helper.h',
       'browser/renderer_host/input/input_router_impl.cc',
       'browser/renderer_host/input/input_router_impl.h',
-      'browser/renderer_host/input/motion_event_android.cc',
-      'browser/renderer_host/input/motion_event_android.h',
       'browser/renderer_host/input/motion_event_web.cc',
       'browser/renderer_host/input/motion_event_web.h',
       'browser/renderer_host/input/mouse_wheel_rails_filter_mac.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index 75789a5..02b112ba 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -794,7 +794,6 @@
       'browser/android/java/java_type_unittest.cc',
       'browser/android/java/jni_helper_unittest.cc',
       'browser/android/url_request_content_job_unittest.cc',
-      'browser/renderer_host/input/motion_event_android_unittest.cc',
       'common/gpu/client/gpu_memory_buffer_impl_surface_texture_unittest.cc',
       'common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc',
       'renderer/java/gin_java_bridge_value_converter_unittest.cc',
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index 0a3f550..d21c88dad 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -55,6 +55,7 @@
 #if defined(OS_WIN)
 #include "base/win/windows_version.h"
 #include "base/win/scoped_com_initializer.h"
+#include "content/common/gpu/media/dxva_video_decode_accelerator.h"
 #include "sandbox/win/src/sandbox.h"
 #endif
 
@@ -435,6 +436,10 @@
     // platforms.
     (void) base::RandUint64();
   }
+
+#if defined(OS_WIN)
+  content::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
+#endif
   return true;
 }
 
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index 31ea238..1c59ad76 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -172,6 +172,8 @@
     "//content/shell/android:content_shell_java_resources",
     "//content/shell/android:content_shell_apk_java",
     "//content/shell/android:content_shell_test_java",
+    "//device/vibration/android:vibration_manager_android",
+    "//device/vibration:mojo_bindings_java",
     "//media/base/android:media_java",
     "//mojo/android:system_java",
     "//net/android:net_java",
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java b/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java
new file mode 100644
index 0000000..634d76bd
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/VibrationManagerImplTest.java
@@ -0,0 +1,114 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import android.os.Vibrator;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.UrlUtils;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content_shell_apk.ContentShellTestBase;
+import org.chromium.device.vibration.VibrationManagerImpl;
+
+/**
+ * Tests java implementation of VibrationManager mojo service on android.
+ */
+public class VibrationManagerImplTest extends ContentShellTestBase {
+    private static final String URL_VIBRATOR_VIBRATE = UrlUtils.encodeHtmlDataUri("<html><body>"
+            + "  <script type=\"text/javascript\">"
+            + "    navigator.vibrate(3000);"
+            + "  </script>"
+            + "</body></html>");
+    private static final String URL_VIBRATOR_CANCEL = UrlUtils.encodeHtmlDataUri("<html><body>"
+            + "  <script type=\"text/javascript\">"
+            + "    navigator.vibrate(10000);"
+            + "    navigator.vibrate(0);"
+            + "  </script>"
+            + "</body></html>");
+
+    private FakeAndroidVibratorWrapper mFakeWrapper;
+
+    // Override AndroidVibratorWrapper API to record the calling.
+    private static class FakeAndroidVibratorWrapper
+            extends VibrationManagerImpl.AndroidVibratorWrapper {
+        // Record the parameters of vibrate() and cancel().
+        public long mMilliSeconds;
+        public boolean mCancelled;
+
+        protected FakeAndroidVibratorWrapper() {
+            super();
+            mMilliSeconds = -1;
+            mCancelled = false;
+        }
+
+        @Override
+        public void vibrate(Vibrator vibrator, long milliseconds) {
+            mMilliSeconds = milliseconds;
+        }
+
+        @Override
+        public void cancel(Vibrator vibrator) {
+            mCancelled = true;
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        launchContentShellWithUrl("about:blank");
+        assertTrue("Page failed to load", waitForActiveShellToBeDoneLoading());
+
+        mFakeWrapper = new FakeAndroidVibratorWrapper();
+        VibrationManagerImpl.setVibratorWrapperForTesting(mFakeWrapper);
+        assertEquals(-1, mFakeWrapper.mMilliSeconds);
+        assertFalse(mFakeWrapper.mCancelled);
+    }
+
+    /**
+     * Inject our fake wrapper into VibrationManagerImpl,
+     * load the webpage which will request vibrate for 3000 milliseconds,
+     * the fake wrapper vibrate() should be called and 3000 milliseconds should be recorded
+     * correctly.
+     */
+    @MediumTest
+    @Feature({"Vibration"})
+    public void testVibrate() throws Throwable {
+        loadNewShell(URL_VIBRATOR_VIBRATE);
+
+        // Waits until VibrationManagerImpl.Vibrate() got called.
+        assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                return mFakeWrapper.mMilliSeconds != -1;
+            }
+        }));
+
+        assertEquals(
+                "Did not get vibrate mMilliSeconds correctly", 3000, mFakeWrapper.mMilliSeconds);
+    }
+
+    /**
+     * Inject our fake wrapper into VibrationManagerImpl,
+     * load the webpage which will request vibrate and then request cancel,
+     * the fake wrapper cancel() should be called.
+     */
+    @MediumTest
+    @Feature({"Vibration"})
+    public void testCancel() throws Throwable {
+        loadNewShell(URL_VIBRATOR_CANCEL);
+
+        // Waits until VibrationManagerImpl.Cancel() got called.
+        assertTrue(CriteriaHelper.pollForUIThreadCriteria(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                return mFakeWrapper.mCancelled;
+            }
+        }));
+
+        assertTrue("Did not get cancelled", mFakeWrapper.mCancelled);
+    }
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
index 0e3fb0b..b21ec85 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
@@ -45,10 +45,10 @@
 public class ImeTest extends ContentShellTestBase {
     private static final String DATA_URL = UrlUtils.encodeHtmlDataUri(
             "<html><head><meta name=\"viewport\""
-            + "content=\"width=device-width, initial-scale=2.0, maximum-scale=2.0\" /></head>"
+            + "content=\"width=device-width\" /></head>"
             + "<body><form action=\"about:blank\">"
             + "<input id=\"input_text\" type=\"text\" /><br/></form><form>"
-            + "<input id=\"input_radio\" type=\"radio\" style=\"width:50px;height:50px\" />"
+            + "<br/><input id=\"input_radio\" type=\"radio\" style=\"width:50px;height:50px\" />"
             + "<br/><textarea id=\"textarea\" rows=\"4\" cols=\"20\"></textarea>"
             + "<br/><textarea id=\"textarea2\" rows=\"4\" cols=\"20\" autocomplete=\"off\">"
             + "</textarea>"
@@ -83,7 +83,7 @@
 
         mCallbackContainer = new TestCallbackHelperContainer(mContentViewCore);
         // TODO(aurimas) remove this wait once crbug.com/179511 is fixed.
-        assertWaitForPageScaleFactorMatch(2);
+        assertWaitForPageScaleFactorMatch(1);
         assertTrue(DOMUtils.waitForNonZeroNodeBounds(
                 mWebContents, "input_text"));
         DOMUtils.clickNode(this, mContentViewCore, "input_text");
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h
index 37f28b1..afaa5816 100644
--- a/content/public/browser/web_contents_observer.h
+++ b/content/public/browser/web_contents_observer.h
@@ -319,8 +319,16 @@
   virtual void DidGetUserGesture() {}
 
   // Called when there has been direct user interaction with the WebContents.
-  // Direct user input includes 1) any mouse down event; 2) any raw key down
-  // event; and 3) any gesture tap event (including taps and scrolls).
+  // The type argument specifies the kind of interaction. Direct user input
+  // signalled through this callback includes:
+  // 1) any mouse down event (blink::WebInputEvent::MouseDown);
+  // 2) the start of a mouse wheel scroll (blink::WebInputEvent::MouseWheel);
+  // 3) any raw key down event (blink::WebInputEvent::RawKeyDown); and
+  // 4) any gesture tap event (blink::WebInputEvent::GestureTapDown).
+  // The start of a mouse wheel scroll is heuristically detected: a mouse
+  // wheel event fired at least 0.1 seconds after any other wheel event is
+  // regarded as the beginning of a scroll. This matches the interval used by
+  // the Blink EventHandler to detect the end of scrolls.
   virtual void DidGetUserInteraction(const blink::WebInputEvent::Type type) {}
 
   // This method is invoked when a RenderViewHost of this WebContents was
diff --git a/content/public/common/page_state.cc b/content/public/common/page_state.cc
index 9d100d3..6174a845 100644
--- a/content/public/common/page_state.cc
+++ b/content/public/common/page_state.cc
@@ -5,6 +5,7 @@
 #include "content/public/common/page_state.h"
 
 #include "base/files/file_path.h"
+#include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/common/page_state_serialization.h"
 
@@ -119,6 +120,15 @@
   return data_;
 }
 
+std::string PageState::GetTopLevelUrlStringTemporaryForBug369661() const {
+  ExplodedPageState state;
+  CHECK(DecodePageState(data_, &state));
+
+  base::NullableString16& url_string = state.top.url_string;
+  CHECK(!url_string.is_null());
+  return base::UTF16ToUTF8(url_string.string());
+}
+
 std::vector<base::FilePath> PageState::GetReferencedFiles() const {
   std::vector<base::FilePath> results;
 
diff --git a/content/public/common/page_state.h b/content/public/common/page_state.h
index c38f961..78782a2 100644
--- a/content/public/common/page_state.h
+++ b/content/public/common/page_state.h
@@ -40,6 +40,7 @@
   bool IsValid() const;
   bool Equals(const PageState& page_state) const;
   const std::string& ToEncodedData() const;
+  std::string GetTopLevelUrlStringTemporaryForBug369661() const;
 
   std::vector<base::FilePath> GetReferencedFiles() const;
   PageState RemovePasswordData() const;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 73d0b77..2708386 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -227,7 +227,9 @@
                        int modifiers) {
   NativeWebKeyboardEvent event;
   BuildSimpleWebKeyEvent(type, key_code, native_key_code, modifiers, &event);
-  web_contents->GetRenderViewHost()->GetWidget()->ForwardKeyboardEvent(event);
+  static_cast<WebContentsImpl*>(web_contents)
+      ->GetFocusedRenderWidgetHost()
+      ->ForwardKeyboardEvent(event);
 }
 
 void GetCookiesCallback(std::string* cookies_out,
diff --git a/content/public/test/content_test_suite_base.cc b/content/public/test/content_test_suite_base.cc
index 6ced225..379ed25 100644
--- a/content/public/test/content_test_suite_base.cc
+++ b/content/public/test/content_test_suite_base.cc
@@ -37,6 +37,7 @@
 #include "net/android/net_jni_registrar.h"
 #include "ui/android/ui_android_jni_registrar.h"
 #include "ui/base/android/ui_base_jni_registrar.h"
+#include "ui/events/android/events_jni_registrar.h"
 #include "ui/gfx/android/gfx_jni_registrar.h"
 #include "ui/gl/android/gl_jni_registrar.h"
 #include "ui/shell_dialogs/android/shell_dialogs_jni_registrar.h"
@@ -88,6 +89,7 @@
   ui::android::RegisterJni(env);
   ui::RegisterUIAndroidJni(env);
   ui::gl::android::RegisterJni(env);
+  ui::events::android::RegisterJni(env);
   ui::shell_dialogs::RegisterJni(env);
 
   content::Compositor::Initialize();
diff --git a/content/renderer/dom_serializer_browsertest.cc b/content/renderer/dom_serializer_browsertest.cc
index a53c705d..c7234e82 100644
--- a/content/renderer/dom_serializer_browsertest.cc
+++ b/content/renderer/dom_serializer_browsertest.cc
@@ -33,7 +33,6 @@
 #include "third_party/WebKit/public/web/WebElementCollection.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebPageSerializer.h"
 #include "third_party/WebKit/public/web/WebPageSerializerClient.h"
 #include "third_party/WebKit/public/web/WebView.h"
@@ -46,7 +45,6 @@
 using blink::WebFrame;
 using blink::WebLocalFrame;
 using blink::WebNode;
-using blink::WebNodeList;
 using blink::WebPageSerializer;
 using blink::WebPageSerializerClient;
 using blink::WebString;
@@ -644,7 +642,6 @@
     WebElement head_element = doc.head();
     ASSERT_TRUE(!head_element.isNull());
     ASSERT_TRUE(!head_element.hasChildNodes());
-    ASSERT_TRUE(head_element.childNodes().length() == 0);
 
     // Do serialization.
     SerializeDomForURL(file_url);
@@ -659,10 +656,9 @@
     ASSERT_TRUE(doc.isHTMLDocument());
     head_element = doc.head();
     ASSERT_TRUE(!head_element.isNull());
-    ASSERT_TRUE(head_element.hasChildNodes());
-    ASSERT_TRUE(head_element.childNodes().length() == 1);
     WebNode meta_node = head_element.firstChild();
     ASSERT_TRUE(!meta_node.isNull());
+    ASSERT_TRUE(meta_node.nextSibling().isNull());
     // Get meta charset info.
     std::string charset_info;
     ASSERT_TRUE(IsMetaElement(meta_node, charset_info));
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc
index 174344d..8d09c20 100644
--- a/content/renderer/media/video_capture_impl.cc
+++ b/content/renderer/media/video_capture_impl.cc
@@ -359,7 +359,21 @@
                    weak_factory_.GetWeakPtr(), buffer_id, buffer));
   } else {
     scoped_refptr<ClientBuffer> buffer;
-    if (storage_type == media::VideoFrame::STORAGE_UNOWNED_MEMORY) {
+    if (storage_type == media::VideoFrame::STORAGE_OPAQUE) {
+      DCHECK(mailbox_holder.mailbox.Verify());
+      DCHECK_EQ(media::PIXEL_FORMAT_ARGB, pixel_format);
+      frame = media::VideoFrame::WrapNativeTexture(
+          pixel_format,
+          mailbox_holder,
+          base::Bind(&SaveReleaseSyncToken, release_sync_token.get()),
+          coded_size,
+          gfx::Rect(coded_size),
+          coded_size,
+          timestamp - first_frame_timestamp_);
+    }
+    else {
+      DCHECK(storage_type == media::VideoFrame::STORAGE_UNOWNED_MEMORY ||
+             storage_type == media::VideoFrame::STORAGE_SHMEM);
       DCHECK_EQ(media::PIXEL_FORMAT_I420, pixel_format);
       const auto& iter = client_buffers_.find(buffer_id);
       DCHECK(iter != client_buffers_.end());
@@ -375,16 +389,8 @@
           buffer->buffer()->handle(),
           0 /* shared_memory_offset */,
           timestamp - first_frame_timestamp_);
-    } else {
-      DCHECK_EQ(storage_type, media::VideoFrame::STORAGE_OPAQUE);
-      DCHECK(mailbox_holder.mailbox.Verify());
-      DCHECK_EQ(media::PIXEL_FORMAT_ARGB, pixel_format);
-      frame = media::VideoFrame::WrapNativeTexture(
-          pixel_format, mailbox_holder,
-          base::Bind(&SaveReleaseSyncToken, release_sync_token.get()),
-          coded_size, gfx::Rect(coded_size), coded_size,
-          timestamp - first_frame_timestamp_);
     }
+    DCHECK(frame);
     buffer_finished_callback = media::BindToCurrentLoop(
         base::Bind(&VideoCaptureImpl::OnClientBufferFinished,
                    weak_factory_.GetWeakPtr(), buffer_id, buffer));
diff --git a/content/renderer/pepper/ppb_image_data_impl.cc b/content/renderer/pepper/ppb_image_data_impl.cc
index 64d269a..385ca22 100644
--- a/content/renderer/pepper/ppb_image_data_impl.cc
+++ b/content/renderer/pepper/ppb_image_data_impl.cc
@@ -19,6 +19,7 @@
 #include "ppapi/thunk/thunk.h"
 #include "skia/ext/platform_canvas.h"
 #include "third_party/skia/include/core/SkColorPriv.h"
+#include "third_party/skia/include/core/SkPixmap.h"
 #include "ui/surface/transport_dib.h"
 
 using ppapi::thunk::PPB_ImageData_API;
@@ -167,18 +168,18 @@
 
 void* ImageDataPlatformBackend::Map() {
   if (!mapped_canvas_) {
-    mapped_canvas_.reset(dib_->GetPlatformCanvas(width_, height_));
+    const bool is_opaque = false;
+    mapped_canvas_.reset(dib_->GetPlatformCanvas(width_, height_, is_opaque));
     if (!mapped_canvas_)
       return NULL;
   }
-  const SkBitmap& bitmap =
-      skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true);
-
-  // Our platform bitmaps are set to opaque by default, which we don't want.
-  const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType);
-
-  bitmap.lockPixels();
-  return bitmap.getAddr32(0, 0);
+  SkPixmap pixmap;
+  skia::GetWritablePixels(mapped_canvas_.get(), &pixmap);
+  DCHECK(pixmap.addr());
+  // SkPixmap does not manage the lifetime of this pointer, so it remains
+  // valid after the object goes out of scope. It will become invalid if
+  // the canvas' backing is destroyed or a pending saveLayer() is resolved.
+  return pixmap.writable_addr32(0, 0);
 }
 
 void ImageDataPlatformBackend::Unmap() {
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 33219e5..d1ac605 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -722,7 +722,6 @@
 RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
     : frame_(NULL),
       is_main_frame_(true),
-      is_local_root_(false),
       render_view_(params.render_view->AsWeakPtr()),
       routing_id_(params.routing_id),
       is_swapped_out_(false),
@@ -830,7 +829,6 @@
 
 void RenderFrameImpl::Initialize() {
   is_main_frame_ = !frame_->parent();
-  is_local_root_ = is_main_frame_ || frame_->parent()->isWebRemoteFrame();
 
   RenderFrameImpl* parent_frame = RenderFrameImpl::FromWebFrame(
       frame_->parent());
@@ -851,7 +849,7 @@
 #endif
   new SharedWorkerRepository(this);
 
-  if (is_local_root_ && !render_frame_proxy_) {
+  if (IsLocalRoot() && !is_swapped_out_) {
     // DevToolsAgent is a RenderFrameObserver, and will destruct itself
     // when |this| is deleted.
     devtools_agent_ = new DevToolsAgent(this);
@@ -4062,6 +4060,13 @@
   return GetRenderWidget()->is_hidden();
 }
 
+bool RenderFrameImpl::IsLocalRoot() const {
+  bool is_local_root = render_widget_ != nullptr;
+  DCHECK_EQ(is_local_root,
+            !(frame_->parent() && frame_->parent()->isWebLocalFrame()));
+  return render_widget_ != nullptr;
+}
+
 // Tell the embedding application that the URL of the active page has changed.
 void RenderFrameImpl::SendDidCommitProvisionalLoad(
     blink::WebFrame* frame,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 2951c59..7474362 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -671,6 +671,8 @@
   void AddObserver(RenderFrameObserver* observer);
   void RemoveObserver(RenderFrameObserver* observer);
 
+  bool IsLocalRoot() const;
+
   // Builds and sends DidCommitProvisionalLoad to the host.
   void SendDidCommitProvisionalLoad(blink::WebFrame* frame,
                                     blink::WebHistoryCommitType commit_type,
@@ -907,10 +909,6 @@
   // |frame_| has been invalidated.
   bool is_main_frame_;
 
-  // Frame is a local root if it is rendered in a process different than parent
-  // or it is a main frame.
-  bool is_local_root_;
-
   base::WeakPtr<RenderViewImpl> render_view_;
   int routing_id_;
   bool is_swapped_out_;
@@ -927,11 +925,9 @@
   // TODO(creis): Remove this after switching to PlzNavigate.
   int proxy_routing_id_;
 
-  // Used when the RenderFrame is a local root. For now, RenderWidgets are
-  // added only when a child frame is in a different process from its parent
-  // frame, but eventually this will also apply to top-level frames.
-  // TODO(kenrb): Correct the above statement when top-level frames have their
-  // own RenderWidgets.
+  // Non-null when the RenderFrame is a local root for compositing, input,
+  // layout, etc. A local frame is also a local root iff it does not have a
+  // parent that is a local frame.
   scoped_refptr<RenderWidget> render_widget_;
 
   // Temporarily holds state pertaining to a navigation that has been initiated
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 3fd5464..d0a0f806 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -152,7 +152,6 @@
 #include "third_party/WebKit/public/web/WebMediaPlayerAction.h"
 #include "third_party/WebKit/public/web/WebNavigationPolicy.h"
 #include "third_party/WebKit/public/web/WebNetworkStateNotifier.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebPageImportanceSignals.h"
 #include "third_party/WebKit/public/web/WebPlugin.h"
 #include "third_party/WebKit/public/web/WebPluginAction.h"
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 72f0975..7e75ee9 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -242,7 +242,8 @@
       plugin_refresh_allowed_(true),
       default_task_runner_(renderer_scheduler->DefaultTaskRunner()),
       loading_task_runner_(renderer_scheduler->LoadingTaskRunner()),
-      web_scrollbar_behavior_(new WebScrollbarBehaviorImpl) {
+      web_scrollbar_behavior_(new WebScrollbarBehaviorImpl),
+      renderer_scheduler_(renderer_scheduler) {
 #if !defined(OS_ANDROID) && !defined(OS_WIN)
   if (g_sandbox_enabled && sandboxEnabled()) {
     sandbox_support_.reset(new RendererBlinkPlatformImpl::SandboxSupport);
@@ -278,6 +279,16 @@
 
 //------------------------------------------------------------------------------
 
+double RendererBlinkPlatformImpl::currentTimeSeconds() {
+  return renderer_scheduler_->CurrentTimeSeconds();
+}
+
+double RendererBlinkPlatformImpl::monotonicallyIncreasingTimeSeconds() {
+  return renderer_scheduler_->MonotonicallyIncreasingTimeSeconds();
+}
+
+//------------------------------------------------------------------------------
+
 blink::WebURLLoader* RendererBlinkPlatformImpl::createURLLoader() {
   ChildThreadImpl* child_thread = ChildThreadImpl::current();
   // There may be no child thread in RenderViewTests.  These tests can still use
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 235a66f..d9279741 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -170,6 +170,8 @@
   void recordRappor(const char* metric,
                     const blink::WebString& sample) override;
   void recordRapporURL(const char* metric, const blink::WebURL& url) override;
+  double currentTimeSeconds() override;
+  double monotonicallyIncreasingTimeSeconds() override;
 
   // Set the PlatformEventObserverBase in |platform_event_observers_| associated
   // with |type| to |observer|. If there was already an observer associated to
@@ -275,6 +277,8 @@
 
   IDMap<PlatformEventObserverBase, IDMapOwnPointer> platform_event_observers_;
 
+  scheduler::RendererScheduler* renderer_scheduler_;  // NOT OWNED
+
   DISALLOW_COPY_AND_ASSIGN(RendererBlinkPlatformImpl);
 };
 
diff --git a/content/renderer/savable_resources.cc b/content/renderer/savable_resources.cc
index d2d28f96..fc9ad350 100644
--- a/content/renderer/savable_resources.cc
+++ b/content/renderer/savable_resources.cc
@@ -18,7 +18,6 @@
 #include "third_party/WebKit/public/web/WebInputElement.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebNodeList.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
 using blink::WebDocument;
@@ -28,7 +27,6 @@
 using blink::WebInputElement;
 using blink::WebLocalFrame;
 using blink::WebNode;
-using blink::WebNodeList;
 using blink::WebString;
 using blink::WebVector;
 using blink::WebView;
diff --git a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
index fc35b28..49da15af 100644
--- a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
+++ b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.cc
@@ -110,6 +110,13 @@
   return result;
 };
 
+// Notifies the adapter's observers that the services have been discovered.
+void NotifyServicesDiscovered(MockBluetoothAdapter* adapter,
+                              MockBluetoothDevice* device) {
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, adapter->GetObservers(),
+                    GattServicesDiscovered(adapter, device));
+}
+
 }  // namespace
 
 namespace content {
@@ -148,6 +155,8 @@
     return GetFailingGATTOperationsAdapter();
   else if (fake_adapter_name == "SecondDiscoveryFindsHeartRateAdapter")
     return GetSecondDiscoveryFindsHeartRateAdapter();
+  else if (fake_adapter_name == "DelayedServicesDiscoveryAdapter")
+    return GetDelayedServicesDiscoveryAdapter();
   else if (fake_adapter_name == "")
     return NULL;
 
@@ -450,6 +459,51 @@
 
 // static
 scoped_refptr<NiceMockBluetoothAdapter>
+LayoutTestBluetoothAdapterProvider::GetDelayedServicesDiscoveryAdapter() {
+  scoped_refptr<NiceMockBluetoothAdapter> adapter(GetEmptyAdapter());
+  scoped_ptr<NiceMockBluetoothDevice> device(GetHeartRateDevice(adapter.get()));
+
+  MockBluetoothAdapter* adapter_ptr = adapter.get();
+  MockBluetoothDevice* device_ptr = device.get();
+
+  // Override the previous mock implementation of CreateGattConnection that
+  // this a NotifyServicesDiscovered task. Instead thsi adapter will not post
+  // that task until GetGattServices is called.
+  ON_CALL(*device, CreateGattConnection(_, _))
+      .WillByDefault(RunCallbackWithResult<0 /* success_callback */>(
+          [adapter_ptr, device_ptr]() {
+            return make_scoped_ptr(new NiceMockBluetoothGattConnection(
+                adapter_ptr, device_ptr->GetAddress()));
+          }));
+
+  ON_CALL(*device, GetGattServices())
+      .WillByDefault(Invoke([adapter_ptr, device_ptr] {
+        std::vector<BluetoothGattService*> services =
+            device_ptr->GetMockServices();
+
+        if (services.size() > 0) {
+          return services;
+        }
+
+        scoped_ptr<NiceMockBluetoothGattService> heart_rate(
+            GetBaseGATTService(device_ptr, kHeartRateServiceUUID));
+
+        device_ptr->AddMockService(heart_rate.Pass());
+        base::ThreadTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::Bind(&NotifyServicesDiscovered,
+                                  make_scoped_refptr(adapter_ptr), device_ptr));
+
+        DCHECK(services.size() == 0);
+        return services;
+      }));
+
+  adapter->AddMockDevice(device.Pass());
+
+  return adapter.Pass();
+}
+
+// static
+scoped_refptr<NiceMockBluetoothAdapter>
 LayoutTestBluetoothAdapterProvider::GetHeartRateAdapter() {
   scoped_refptr<NiceMockBluetoothAdapter> adapter(GetEmptyAdapter());
   // Used by lambdas that need the adapter.
@@ -656,11 +710,14 @@
   scoped_ptr<NiceMockBluetoothDevice> device(
       GetBaseDevice(adapter, device_name, uuids, address));
 
-  BluetoothDevice* device_ptr = device.get();
+  MockBluetoothDevice* device_ptr = device.get();
 
   ON_CALL(*device, CreateGattConnection(_, _))
       .WillByDefault(RunCallbackWithResult<0 /* success_callback */>(
           [adapter, device_ptr]() {
+            base::ThreadTaskRunnerHandle::Get()->PostTask(
+                FROM_HERE, base::Bind(&NotifyServicesDiscovered,
+                                      make_scoped_refptr(adapter), device_ptr));
             return make_scoped_ptr(new NiceMockBluetoothGattConnection(
                 adapter, device_ptr->GetAddress()));
           }));
diff --git a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
index 39431b26..d6204f24 100644
--- a/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
+++ b/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h
@@ -199,6 +199,18 @@
   static scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
   GetGenericAccessAdapter();
 
+  // |DelayedServicesDiscoveryAdapter|
+  // Inherits from |EmptyAdapter|
+  // Internal Structure:
+  //   - Heart Rate Device
+  //      - Generic Access UUID (0x1800)
+  //      - Heart Rate UUID (0x180D)
+  //      - Heart Rate Service (No services will be returned the first time
+  //                            GetServices is called. Subsequent calls will
+  //                            return the Heart Rate Service)
+  static scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
+  GetDelayedServicesDiscoveryAdapter();
+
   // |HeartRateAdapter|
   // Inherits from |EmptyAdapter|
   // Internal Structure:
diff --git a/content/shell/browser/shell_views.cc b/content/shell/browser/shell_views.cc
index 4ce0fa68..1c6a1f9 100644
--- a/content/shell/browser/shell_views.cc
+++ b/content/shell/browser/shell_views.cc
@@ -38,6 +38,7 @@
 
 #if defined(OS_CHROMEOS)
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "ui/aura/test/test_screen.h"
 #include "ui/wm/test/wm_test_helper.h"
 #else  // !defined(OS_CHROMEOS)
@@ -412,6 +413,10 @@
 #endif
 #if defined(OS_CHROMEOS)
   chromeos::DBusThreadManager::Initialize();
+  bluez::BluezDBusManager::Initialize(
+      chromeos::DBusThreadManager::Get()->GetSystemBus(),
+      chromeos::DBusThreadManager::Get()->IsUsingStub(
+          chromeos::DBusClientBundle::BLUETOOTH));
   test_screen_ = aura::TestScreen::Create(gfx::Size());
   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen_);
   wm_test_helper_ = new wm::WMTestHelper(default_window_size,
@@ -437,6 +442,7 @@
   platform_ = NULL;
 #if defined(OS_CHROMEOS)
   device::BluetoothAdapterFactory::Shutdown();
+  bluez::BluezDBusManager::Shutdown();
   chromeos::DBusThreadManager::Shutdown();
 #endif
   aura::Env::DeleteInstance();
diff --git a/content/test/data/page_with_input_field.html b/content/test/data/page_with_input_field.html
index 494456a..87426ac2 100644
--- a/content/test/data/page_with_input_field.html
+++ b/content/test/data/page_with_input_field.html
@@ -8,6 +8,11 @@
   inputField.focus();
 }
 
+function getInputFieldText() {
+  var inputField = document.getElementById("text-field");
+  return inputField.value;
+}
+
 function onInputFocus() {
   domAutomationController.setAutomationId(0);
   domAutomationController.send("input-focus");
diff --git a/content/test/data/touch_selection.html b/content/test/data/touch_selection.html
index 7bf8644..dc8ab06 100644
--- a/content/test/data/touch_selection.html
+++ b/content/test/data/touch_selection.html
@@ -4,7 +4,7 @@
 <script>
 
 function focus_textfield() {
-  document.getElementById("textfield").focus();
+  document.getElementById('textfield').focus();
   // Focusing the textfiled selects its text. Collapse selection to a cursor.
   window.getSelection().collapseToStart();
 }
@@ -26,6 +26,10 @@
   get_point_inside(document.getElementById('textfield'));
 }
 
+function empty_textfield() {
+  document.getElementById('textfield').value = "";
+}
+
 </script>
 
 </html>
diff --git a/content/test/fake_renderer_scheduler.cc b/content/test/fake_renderer_scheduler.cc
index a869bf0..f0ae6c7 100644
--- a/content/test/fake_renderer_scheduler.cc
+++ b/content/test/fake_renderer_scheduler.cc
@@ -118,4 +118,12 @@
 void FakeRendererScheduler::SetTimerQueueSuspensionWhenBackgroundedEnabled(
     bool enabled) {}
 
+double FakeRendererScheduler::CurrentTimeSeconds() const {
+  return 0.0;
+}
+
+double FakeRendererScheduler::MonotonicallyIncreasingTimeSeconds() const {
+  return 0.0;
+}
+
 }  // namespace content
diff --git a/content/test/fake_renderer_scheduler.h b/content/test/fake_renderer_scheduler.h
index 168b428..4367f3f1 100644
--- a/content/test/fake_renderer_scheduler.h
+++ b/content/test/fake_renderer_scheduler.h
@@ -51,6 +51,8 @@
   void SuspendTimerQueue() override;
   void ResumeTimerQueue() override;
   void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) override;
+  double CurrentTimeSeconds() const override;
+  double MonotonicallyIncreasingTimeSeconds() const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FakeRendererScheduler);
diff --git a/device/BUILD.gn b/device/BUILD.gn
index bb27c5a..0a61c72c 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -30,22 +30,16 @@
     "battery/battery_status_manager_win_unittest.cc",
     "battery/battery_status_service_unittest.cc",
     "bluetooth/bluetooth_adapter_mac_unittest.mm",
-    "bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc",
     "bluetooth/bluetooth_adapter_unittest.cc",
     "bluetooth/bluetooth_adapter_win_unittest.cc",
-    "bluetooth/bluetooth_advertisement_chromeos_unittest.cc",
     "bluetooth/bluetooth_advertisement_unittest.cc",
-    "bluetooth/bluetooth_audio_sink_chromeos_unittest.cc",
-    "bluetooth/bluetooth_chromeos_unittest.cc",
     "bluetooth/bluetooth_device_unittest.cc",
     "bluetooth/bluetooth_device_win_unittest.cc",
     "bluetooth/bluetooth_discovery_filter_unittest.cc",
     "bluetooth/bluetooth_gatt_characteristic_unittest.cc",
-    "bluetooth/bluetooth_gatt_chromeos_unittest.cc",
     "bluetooth/bluetooth_gatt_service_unittest.cc",
     "bluetooth/bluetooth_low_energy_win_unittest.cc",
     "bluetooth/bluetooth_service_record_win_unittest.cc",
-    "bluetooth/bluetooth_socket_chromeos_unittest.cc",
     "bluetooth/bluetooth_task_manager_win_unittest.cc",
     "bluetooth/bluetooth_uuid_unittest.cc",
     "bluetooth/test/bluetooth_test.cc",
@@ -146,16 +140,28 @@
   }
 
   if (is_chromeos) {
-    configs += [ "//build/config/linux:dbus" ]
-
     deps += [
       "//chromeos",
       "//chromeos:test_support",
       "//chromeos:test_support_without_gmock",
-      "//dbus",
     ]
   }
 
+  if (is_chromeos || is_linux) {
+    configs += [ "//build/config/linux:dbus" ]
+
+    sources += [
+      "bluetooth/bluetooth_adapter_profile_bluez_unittest.cc",
+      "bluetooth/bluetooth_advertisement_bluez_unittest.cc",
+      "bluetooth/bluetooth_audio_sink_bluez_unittest.cc",
+      "bluetooth/bluetooth_bluez_unittest.cc",
+      "bluetooth/bluetooth_gatt_bluez_unittest.cc",
+      "bluetooth/bluetooth_socket_bluez_unittest.cc",
+    ]
+
+    deps += [ "//dbus" ]
+  }
+
   if (is_posix && !is_android && !is_mac) {
     libs = [ "rt" ]
   }
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 5edb17c..06a657a 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -29,24 +29,16 @@
     "bluetooth_adapter.h",
     "bluetooth_adapter_android.cc",
     "bluetooth_adapter_android.h",
-    "bluetooth_adapter_chromeos.cc",
-    "bluetooth_adapter_chromeos.h",
     "bluetooth_adapter_factory.cc",
     "bluetooth_adapter_factory.h",
     "bluetooth_adapter_mac.h",
     "bluetooth_adapter_mac.mm",
-    "bluetooth_adapter_profile_chromeos.cc",
-    "bluetooth_adapter_profile_chromeos.h",
     "bluetooth_adapter_win.cc",
     "bluetooth_adapter_win.h",
     "bluetooth_advertisement.cc",
     "bluetooth_advertisement.h",
-    "bluetooth_advertisement_chromeos.cc",
-    "bluetooth_advertisement_chromeos.h",
     "bluetooth_audio_sink.cc",
     "bluetooth_audio_sink.h",
-    "bluetooth_audio_sink_chromeos.cc",
-    "bluetooth_audio_sink_chromeos.h",
     "bluetooth_channel_mac.h",
     "bluetooth_channel_mac.mm",
     "bluetooth_classic_device_mac.h",
@@ -55,8 +47,6 @@
     "bluetooth_device.h",
     "bluetooth_device_android.cc",
     "bluetooth_device_android.h",
-    "bluetooth_device_chromeos.cc",
-    "bluetooth_device_chromeos.h",
     "bluetooth_device_mac.h",
     "bluetooth_device_mac.mm",
     "bluetooth_device_win.cc",
@@ -72,14 +62,12 @@
     "bluetooth_gatt_characteristic.h",
     "bluetooth_gatt_connection.cc",
     "bluetooth_gatt_connection.h",
-    "bluetooth_gatt_connection_chromeos.cc",
-    "bluetooth_gatt_connection_chromeos.h",
     "bluetooth_gatt_descriptor.cc",
     "bluetooth_gatt_descriptor.h",
     "bluetooth_gatt_notify_session.cc",
     "bluetooth_gatt_notify_session.h",
-    "bluetooth_gatt_notify_session_chromeos.cc",
-    "bluetooth_gatt_notify_session_chromeos.h",
+    "bluetooth_gatt_notify_session_android.cc",
+    "bluetooth_gatt_notify_session_android.h",
     "bluetooth_gatt_service.cc",
     "bluetooth_gatt_service.h",
     "bluetooth_init_win.cc",
@@ -96,26 +84,16 @@
     "bluetooth_low_energy_discovery_manager_mac.mm",
     "bluetooth_low_energy_win.cc",
     "bluetooth_low_energy_win.h",
-    "bluetooth_pairing_chromeos.cc",
-    "bluetooth_pairing_chromeos.h",
     "bluetooth_remote_gatt_characteristic_android.cc",
     "bluetooth_remote_gatt_characteristic_android.h",
-    "bluetooth_remote_gatt_characteristic_chromeos.cc",
-    "bluetooth_remote_gatt_characteristic_chromeos.h",
-    "bluetooth_remote_gatt_descriptor_chromeos.cc",
-    "bluetooth_remote_gatt_descriptor_chromeos.h",
     "bluetooth_remote_gatt_service_android.cc",
     "bluetooth_remote_gatt_service_android.h",
-    "bluetooth_remote_gatt_service_chromeos.cc",
-    "bluetooth_remote_gatt_service_chromeos.h",
     "bluetooth_rfcomm_channel_mac.h",
     "bluetooth_rfcomm_channel_mac.mm",
     "bluetooth_service_record_win.cc",
     "bluetooth_service_record_win.h",
     "bluetooth_socket.cc",
     "bluetooth_socket.h",
-    "bluetooth_socket_chromeos.cc",
-    "bluetooth_socket_chromeos.h",
     "bluetooth_socket_mac.h",
     "bluetooth_socket_mac.mm",
     "bluetooth_socket_net.cc",
@@ -148,10 +126,11 @@
   }
 
   if (is_chromeos) {
-    deps += [
-      "//chromeos",
-      "//dbus",
-    ]
+    deps += [ "//chromeos" ]
+  }
+
+  if (is_chromeos || is_linux) {
+    deps += [ "//dbus" ]
   }
 
   if (is_mac) {
@@ -162,11 +141,32 @@
     libs = [ "setupapi.lib" ]
   }
 
-  # This block will also build for Linux once we write the linux
-  # implementation of BluezDbusManager.
-  if (is_chromeos) {
-    defines += [ "DEVICE_BLUETOOTH_IMPLEMENTATION" ]
+  if (is_chromeos || is_linux) {
     sources += [
+      "bluetooth_adapter_bluez.cc",
+      "bluetooth_adapter_bluez.h",
+      "bluetooth_adapter_profile_bluez.cc",
+      "bluetooth_adapter_profile_bluez.h",
+      "bluetooth_advertisement_bluez.cc",
+      "bluetooth_advertisement_bluez.h",
+      "bluetooth_audio_sink_bluez.cc",
+      "bluetooth_audio_sink_bluez.h",
+      "bluetooth_device_bluez.cc",
+      "bluetooth_device_bluez.h",
+      "bluetooth_gatt_connection_bluez.cc",
+      "bluetooth_gatt_connection_bluez.h",
+      "bluetooth_gatt_notify_session_bluez.cc",
+      "bluetooth_gatt_notify_session_bluez.h",
+      "bluetooth_pairing_bluez.cc",
+      "bluetooth_pairing_bluez.h",
+      "bluetooth_remote_gatt_characteristic_bluez.cc",
+      "bluetooth_remote_gatt_characteristic_bluez.h",
+      "bluetooth_remote_gatt_descriptor_bluez.cc",
+      "bluetooth_remote_gatt_descriptor_bluez.h",
+      "bluetooth_remote_gatt_service_bluez.cc",
+      "bluetooth_remote_gatt_service_bluez.h",
+      "bluetooth_socket_bluez.cc",
+      "bluetooth_socket_bluez.h",
       "dbus/bluetooth_adapter_client.cc",
       "dbus/bluetooth_adapter_client.h",
       "dbus/bluetooth_agent_manager_client.cc",
@@ -210,6 +210,8 @@
       "dbus/bluez_dbus_client.h",
       "dbus/bluez_dbus_manager.cc",
       "dbus/bluez_dbus_manager.h",
+      "dbus/dbus_thread_manager_linux.cc",
+      "dbus/dbus_thread_manager_linux.h",
       "dbus/fake_bluetooth_adapter_client.cc",
       "dbus/fake_bluetooth_adapter_client.h",
       "dbus/fake_bluetooth_agent_manager_client.cc",
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattCharacteristic.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattCharacteristic.java
index 845026d..dd0d2617 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattCharacteristic.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothRemoteGattCharacteristic.java
@@ -91,6 +91,18 @@
         return mCharacteristic.getProperties();
     }
 
+    // Implements BluetoothRemoteGattCharacteristicAndroid::StartNotifySession.
+    @CalledByNative
+    private boolean startNotifySession() {
+        if (!mChromeBluetoothDevice.mBluetoothGatt.setCharacteristicNotification(
+                    mCharacteristic, true)) {
+            Log.i(TAG, "startNotifySession setCharacteristicNotification failed.");
+            return false;
+        }
+        Log.i(TAG, "startNotifySession.");
+        return true;
+    }
+
     // Implements BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic.
     @CalledByNative
     private boolean readRemoteCharacteristic() {
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
index e8e6306..baeec8e9 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
@@ -294,6 +294,11 @@
             return mGatt.readCharacteristic(characteristic.mCharacteristic);
         }
 
+        boolean setCharacteristicNotification(
+                BluetoothGattCharacteristicWrapper characteristic, boolean enable) {
+            return mGatt.setCharacteristicNotification(characteristic.mCharacteristic, enable);
+        }
+
         boolean writeCharacteristic(BluetoothGattCharacteristicWrapper characteristic) {
             return mGatt.writeCharacteristic(characteristic.mCharacteristic);
         }
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp
index 90306d10..b4f90f2 100644
--- a/device/bluetooth/bluetooth.gyp
+++ b/device/bluetooth/bluetooth.gyp
@@ -32,24 +32,16 @@
         'bluetooth_adapter.h',
         'bluetooth_adapter_android.cc',
         'bluetooth_adapter_android.h',
-        'bluetooth_adapter_chromeos.cc',
-        'bluetooth_adapter_chromeos.h',
         'bluetooth_adapter_factory.cc',
         'bluetooth_adapter_factory.h',
         'bluetooth_adapter_mac.h',
         'bluetooth_adapter_mac.mm',
-        "bluetooth_adapter_profile_chromeos.cc",
-        "bluetooth_adapter_profile_chromeos.h",
         'bluetooth_adapter_win.cc',
         'bluetooth_adapter_win.h',
         'bluetooth_advertisement.cc',
         'bluetooth_advertisement.h',
-        'bluetooth_advertisement_chromeos.cc',
-        'bluetooth_advertisement_chromeos.h',
         'bluetooth_audio_sink.cc',
         'bluetooth_audio_sink.h',
-        'bluetooth_audio_sink_chromeos.cc',
-        'bluetooth_audio_sink_chromeos.h',
         'bluetooth_channel_mac.mm',
         'bluetooth_channel_mac.h',
         'bluetooth_classic_device_mac.mm',
@@ -58,8 +50,6 @@
         'bluetooth_device.h',
         'bluetooth_device_android.h',
         'bluetooth_device_android.cc',
-        'bluetooth_device_chromeos.cc',
-        'bluetooth_device_chromeos.h',
         'bluetooth_device_mac.mm',
         'bluetooth_device_mac.h',
         'bluetooth_device_win.cc',
@@ -75,14 +65,12 @@
         'bluetooth_gatt_characteristic.h',
         'bluetooth_gatt_connection.cc',
         'bluetooth_gatt_connection.h',
-        'bluetooth_gatt_connection_chromeos.cc',
-        'bluetooth_gatt_connection_chromeos.h',
         'bluetooth_gatt_descriptor.cc',
         'bluetooth_gatt_descriptor.h',
         'bluetooth_gatt_notify_session.cc',
         'bluetooth_gatt_notify_session.h',
-        'bluetooth_gatt_notify_session_chromeos.cc',
-        'bluetooth_gatt_notify_session_chromeos.h',
+        'bluetooth_gatt_notify_session_android.cc',
+        'bluetooth_gatt_notify_session_android.h',
         'bluetooth_gatt_service.cc',
         'bluetooth_gatt_service.h',
         'bluetooth_init_win.cc',
@@ -99,26 +87,16 @@
         'bluetooth_low_energy_discovery_manager_mac.mm',
         'bluetooth_low_energy_win.cc',
         'bluetooth_low_energy_win.h',
-        'bluetooth_pairing_chromeos.cc',
-        'bluetooth_pairing_chromeos.h',
         'bluetooth_remote_gatt_characteristic_android.cc',
         'bluetooth_remote_gatt_characteristic_android.h',
-        'bluetooth_remote_gatt_characteristic_chromeos.cc',
-        'bluetooth_remote_gatt_characteristic_chromeos.h',
-        'bluetooth_remote_gatt_descriptor_chromeos.cc',
-        'bluetooth_remote_gatt_descriptor_chromeos.h',
         'bluetooth_remote_gatt_service_android.cc',
         'bluetooth_remote_gatt_service_android.h',
-        'bluetooth_remote_gatt_service_chromeos.cc',
-        'bluetooth_remote_gatt_service_chromeos.h',
         'bluetooth_rfcomm_channel_mac.mm',
         'bluetooth_rfcomm_channel_mac.h',
         'bluetooth_service_record_win.cc',
         'bluetooth_service_record_win.h',
         'bluetooth_socket.cc',
         'bluetooth_socket.h',
-        'bluetooth_socket_chromeos.cc',
-        'bluetooth_socket_chromeos.h',
         'bluetooth_socket_mac.h',
         'bluetooth_socket_mac.mm',
         'bluetooth_socket_net.cc',
@@ -135,11 +113,35 @@
       'conditions': [
         # This block will also build for Linux once we write the linux
         # implementation of BluezDbusManager.
-        ['chromeos==1', {
+        ['chromeos==1 or OS=="linux"', {
          'defines': [
             'DEVICE_BLUETOOTH_IMPLEMENTATION',
           ],
           'sources': [
+            'bluetooth_adapter_bluez.cc',
+            'bluetooth_adapter_bluez.h',
+            'bluetooth_adapter_profile_bluez.cc',
+            'bluetooth_adapter_profile_bluez.h',
+            'bluetooth_advertisement_bluez.cc',
+            'bluetooth_advertisement_bluez.h',
+            'bluetooth_audio_sink_bluez.cc',
+            'bluetooth_audio_sink_bluez.h',
+            'bluetooth_device_bluez.cc',
+            'bluetooth_device_bluez.h',
+            'bluetooth_gatt_connection_bluez.cc',
+            'bluetooth_gatt_connection_bluez.h',
+            'bluetooth_gatt_notify_session_bluez.cc',
+            'bluetooth_gatt_notify_session_bluez.h',
+            'bluetooth_pairing_bluez.cc',
+            'bluetooth_pairing_bluez.h',
+            'bluetooth_remote_gatt_characteristic_bluez.cc',
+            'bluetooth_remote_gatt_characteristic_bluez.h',
+            'bluetooth_remote_gatt_descriptor_bluez.cc',
+            'bluetooth_remote_gatt_descriptor_bluez.h',
+            'bluetooth_remote_gatt_service_bluez.cc',
+            'bluetooth_remote_gatt_service_bluez.h',
+            'bluetooth_socket_bluez.cc',
+            'bluetooth_socket_bluez.h',
             'dbus/bluetooth_adapter_client.cc',
             'dbus/bluetooth_adapter_client.h',
             'dbus/bluetooth_le_advertising_manager_client.cc',
@@ -183,6 +185,8 @@
             'dbus/bluez_dbus_client.h',
             'dbus/bluez_dbus_manager.cc',
             'dbus/bluez_dbus_manager.h',
+            'dbus/dbus_thread_manager_linux.cc',
+            'dbus/dbus_thread_manager_linux.h',
             'dbus/fake_bluetooth_adapter_client.cc',
             'dbus/fake_bluetooth_adapter_client.h',
             'dbus/fake_bluetooth_le_advertising_manager_client.cc',
@@ -222,17 +226,19 @@
             'dbus/fake_bluetooth_profile_service_provider.cc',
             'dbus/fake_bluetooth_profile_service_provider.h',
           ],
-        }],
-        ['chromeos==1', {
           'dependencies': [
             '../../build/linux/system.gyp:dbus',
-            '../../chromeos/chromeos.gyp:chromeos',
             '../../dbus/dbus.gyp:dbus',
           ],
           'export_dependent_settings': [
             '../../build/linux/system.gyp:dbus'
           ]
         }],
+        ['chromeos==1', {
+          'dependencies': [
+            '../../chromeos/chromeos.gyp:chromeos',
+          ],
+        }],
         ['OS == "android"', {
           'dependencies': [
             'device_bluetooth_java',
diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc
index d48f5383..b97ac24 100644
--- a/device/bluetooth/bluetooth_adapter.cc
+++ b/device/bluetooth/bluetooth_adapter.cc
@@ -19,7 +19,7 @@
 }
 
 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && !defined(OS_MACOSX) && \
-    !defined(OS_WIN)
+    !defined(OS_WIN) && !defined(OS_LINUX)
 // static
 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
     const InitCallback& init_callback) {
@@ -31,7 +31,7 @@
   return weak_ptr_factory_.GetWeakPtr();
 }
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 void BluetoothAdapter::Shutdown() {
   NOTIMPLEMENTED();
 }
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h
index 63969fc..71b44b9 100644
--- a/device/bluetooth/bluetooth_adapter.h
+++ b/device/bluetooth/bluetooth_adapter.h
@@ -221,7 +221,7 @@
   // Returns a weak pointer to an existing adapter for testing purposes only.
   base::WeakPtr<BluetoothAdapter> GetWeakPtrForTesting();
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
   // Shutdown the adapter: tear down and clean up all objects owned by
   // BluetoothAdapter. After this call, the BluetoothAdapter will behave as if
   // no Bluetooth controller exists in the local system. |IsPresent| will return
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_bluez.cc
similarity index 70%
rename from device/bluetooth/bluetooth_adapter_chromeos.cc
rename to device/bluetooth/bluetooth_adapter_bluez.cc
index 55d0bef..b00db70 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_bluez.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 
 #include <string>
 
@@ -13,18 +13,17 @@
 #include "base/sequenced_task_runner.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
-#include "chromeos/system/devicetype.h"
-#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
-#include "device/bluetooth/bluetooth_advertisement_chromeos.h"
-#include "device/bluetooth/bluetooth_audio_sink_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_profile_bluez.h"
+#include "device/bluetooth/bluetooth_advertisement_bluez.h"
+#include "device/bluetooth/bluetooth_audio_sink_bluez.h"
 #include "device/bluetooth/bluetooth_device.h"
-#include "device/bluetooth/bluetooth_device_chromeos.h"
+#include "device/bluetooth/bluetooth_device_bluez.h"
 #include "device/bluetooth/bluetooth_discovery_session_outcome.h"
-#include "device/bluetooth/bluetooth_pairing_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
-#include "device/bluetooth/bluetooth_socket_chromeos.h"
+#include "device/bluetooth/bluetooth_pairing_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h"
+#include "device/bluetooth/bluetooth_socket_bluez.h"
 #include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 #include "device/bluetooth/dbus/bluetooth_adapter_client.h"
@@ -35,6 +34,10 @@
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
+#if defined(OS_CHROMEOS)
+#include "chromeos/system/devicetype.h"
+#endif
+
 using device::BluetoothAdapter;
 using device::BluetoothAudioSink;
 using device::BluetoothDevice;
@@ -55,20 +58,20 @@
   if (error_name == bluetooth_agent_manager::kErrorDoesNotExist)
     return;
 
-  LOG(WARNING) << "Failed to unregister pairing agent: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << "Failed to unregister pairing agent: " << error_name << ": "
+               << error_message;
 }
 
 UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA(
     const std::string& error_name) {
   if (error_name == bluez::BluetoothAdapterClient::kUnknownAdapterError) {
-    return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_UNKNOWN_ADAPTER;
+    return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_UNKNOWN_ADAPTER;
   } else if (error_name == bluez::BluetoothAdapterClient::kNoResponseError) {
-    return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_NO_RESPONSE;
+    return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_NO_RESPONSE;
   } else if (error_name == bluetooth_device::kErrorInProgress) {
-    return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_IN_PROGRESS;
+    return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_IN_PROGRESS;
   } else if (error_name == bluetooth_device::kErrorNotReady) {
-    return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_NOT_READY;
+    return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_NOT_READY;
   } else if (error_name == bluetooth_device::kErrorFailed) {
     return UMABluetoothDiscoverySessionOutcome::FAILED;
   } else {
@@ -84,20 +87,20 @@
 // static
 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter(
     const InitCallback& init_callback) {
-  return chromeos::BluetoothAdapterChromeOS::CreateAdapter();
+  return bluez::BluetoothAdapterBlueZ::CreateAdapter();
 }
 
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
 // static
-base::WeakPtr<BluetoothAdapter> BluetoothAdapterChromeOS::CreateAdapter() {
-  BluetoothAdapterChromeOS* adapter = new BluetoothAdapterChromeOS();
+base::WeakPtr<BluetoothAdapter> BluetoothAdapterBlueZ::CreateAdapter() {
+  BluetoothAdapterBlueZ* adapter = new BluetoothAdapterBlueZ();
   return adapter->weak_ptr_factory_.GetWeakPtr();
 }
 
-void BluetoothAdapterChromeOS::Shutdown() {
+void BluetoothAdapterBlueZ::Shutdown() {
   if (dbus_is_shutdown_)
     return;
   DCHECK(bluez::BluezDBusManager::IsInitialized())
@@ -133,7 +136,7 @@
   dbus_is_shutdown_ = true;
 }
 
-BluetoothAdapterChromeOS::BluetoothAdapterChromeOS()
+BluetoothAdapterBlueZ::BluetoothAdapterBlueZ()
     : dbus_is_shutdown_(false),
       num_discovery_sessions_(0),
       discovery_request_pending_(false),
@@ -162,11 +165,11 @@
   }
 }
 
-BluetoothAdapterChromeOS::~BluetoothAdapterChromeOS() {
+BluetoothAdapterBlueZ::~BluetoothAdapterBlueZ() {
   Shutdown();
 }
 
-std::string BluetoothAdapterChromeOS::GetAddress() const {
+std::string BluetoothAdapterBlueZ::GetAddress() const {
   if (!IsPresent())
     return std::string();
 
@@ -179,7 +182,7 @@
   return BluetoothDevice::CanonicalizeAddress(properties->address.value());
 }
 
-std::string BluetoothAdapterChromeOS::GetName() const {
+std::string BluetoothAdapterBlueZ::GetName() const {
   if (!IsPresent())
     return std::string();
 
@@ -192,9 +195,9 @@
   return properties->alias.value();
 }
 
-void BluetoothAdapterChromeOS::SetName(const std::string& name,
-                                       const base::Closure& callback,
-                                       const ErrorCallback& error_callback) {
+void BluetoothAdapterBlueZ::SetName(const std::string& name,
+                                    const base::Closure& callback,
+                                    const ErrorCallback& error_callback) {
   if (!IsPresent()) {
     error_callback.Run();
     return;
@@ -205,19 +208,19 @@
       ->GetProperties(object_path_)
       ->alias.Set(
           name,
-          base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted,
+          base::Bind(&BluetoothAdapterBlueZ::OnPropertyChangeCompleted,
                      weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
-bool BluetoothAdapterChromeOS::IsInitialized() const {
+bool BluetoothAdapterBlueZ::IsInitialized() const {
   return true;
 }
 
-bool BluetoothAdapterChromeOS::IsPresent() const {
+bool BluetoothAdapterBlueZ::IsPresent() const {
   return !dbus_is_shutdown_ && !object_path_.value().empty();
 }
 
-bool BluetoothAdapterChromeOS::IsPowered() const {
+bool BluetoothAdapterBlueZ::IsPowered() const {
   if (!IsPresent())
     return false;
 
@@ -229,10 +232,9 @@
   return properties->powered.value();
 }
 
-void BluetoothAdapterChromeOS::SetPowered(
-    bool powered,
-    const base::Closure& callback,
-    const ErrorCallback& error_callback) {
+void BluetoothAdapterBlueZ::SetPowered(bool powered,
+                                       const base::Closure& callback,
+                                       const ErrorCallback& error_callback) {
   if (!IsPresent()) {
     error_callback.Run();
     return;
@@ -243,11 +245,11 @@
       ->GetProperties(object_path_)
       ->powered.Set(
           powered,
-          base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted,
+          base::Bind(&BluetoothAdapterBlueZ::OnPropertyChangeCompleted,
                      weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
-bool BluetoothAdapterChromeOS::IsDiscoverable() const {
+bool BluetoothAdapterBlueZ::IsDiscoverable() const {
   if (!IsPresent())
     return false;
 
@@ -259,7 +261,7 @@
   return properties->discoverable.value();
 }
 
-void BluetoothAdapterChromeOS::SetDiscoverable(
+void BluetoothAdapterBlueZ::SetDiscoverable(
     bool discoverable,
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
@@ -273,11 +275,11 @@
       ->GetProperties(object_path_)
       ->discoverable.Set(
           discoverable,
-          base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoverable,
+          base::Bind(&BluetoothAdapterBlueZ::OnSetDiscoverable,
                      weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
-bool BluetoothAdapterChromeOS::IsDiscovering() const {
+bool BluetoothAdapterBlueZ::IsDiscovering() const {
   if (!IsPresent())
     return false;
 
@@ -289,45 +291,37 @@
   return properties->discovering.value();
 }
 
-void BluetoothAdapterChromeOS::CreateRfcommService(
+void BluetoothAdapterBlueZ::CreateRfcommService(
     const BluetoothUUID& uuid,
     const ServiceOptions& options,
     const CreateServiceCallback& callback,
     const CreateServiceErrorCallback& error_callback) {
   DCHECK(!dbus_is_shutdown_);
-  VLOG(1) << object_path_.value() << ": Creating RFCOMM service: "
-          << uuid.canonical_value();
-  scoped_refptr<BluetoothSocketChromeOS> socket =
-      BluetoothSocketChromeOS::CreateBluetoothSocket(
-          ui_task_runner_, socket_thread_);
-  socket->Listen(this,
-                 BluetoothSocketChromeOS::kRfcomm,
-                 uuid,
-                 options,
-                 base::Bind(callback, socket),
-                 error_callback);
+  VLOG(1) << object_path_.value()
+          << ": Creating RFCOMM service: " << uuid.canonical_value();
+  scoped_refptr<BluetoothSocketBlueZ> socket =
+      BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner_,
+                                                  socket_thread_);
+  socket->Listen(this, BluetoothSocketBlueZ::kRfcomm, uuid, options,
+                 base::Bind(callback, socket), error_callback);
 }
 
-void BluetoothAdapterChromeOS::CreateL2capService(
+void BluetoothAdapterBlueZ::CreateL2capService(
     const BluetoothUUID& uuid,
     const ServiceOptions& options,
     const CreateServiceCallback& callback,
     const CreateServiceErrorCallback& error_callback) {
   DCHECK(!dbus_is_shutdown_);
-  VLOG(1) << object_path_.value() << ": Creating L2CAP service: "
-          << uuid.canonical_value();
-  scoped_refptr<BluetoothSocketChromeOS> socket =
-      BluetoothSocketChromeOS::CreateBluetoothSocket(
-          ui_task_runner_, socket_thread_);
-  socket->Listen(this,
-                 BluetoothSocketChromeOS::kL2cap,
-                 uuid,
-                 options,
-                 base::Bind(callback, socket),
-                 error_callback);
+  VLOG(1) << object_path_.value()
+          << ": Creating L2CAP service: " << uuid.canonical_value();
+  scoped_refptr<BluetoothSocketBlueZ> socket =
+      BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner_,
+                                                  socket_thread_);
+  socket->Listen(this, BluetoothSocketBlueZ::kL2cap, uuid, options,
+                 base::Bind(callback, socket), error_callback);
 }
 
-void BluetoothAdapterChromeOS::RegisterAudioSink(
+void BluetoothAdapterBlueZ::RegisterAudioSink(
     const BluetoothAudioSink::Options& options,
     const device::BluetoothAdapter::AcquiredCallback& callback,
     const BluetoothAudioSink::ErrorCallback& error_callback) {
@@ -336,53 +330,52 @@
     error_callback.Run(BluetoothAudioSink::ERROR_INVALID_ADAPTER);
     return;
   }
-  scoped_refptr<BluetoothAudioSinkChromeOS> audio_sink(
-      new BluetoothAudioSinkChromeOS(this));
-  audio_sink->Register(
-      options, base::Bind(&BluetoothAdapterChromeOS::OnRegisterAudioSink,
-                          weak_ptr_factory_.GetWeakPtr(), callback,
-                          error_callback, audio_sink),
-      error_callback);
+  scoped_refptr<BluetoothAudioSinkBlueZ> audio_sink(
+      new BluetoothAudioSinkBlueZ(this));
+  audio_sink->Register(options,
+                       base::Bind(&BluetoothAdapterBlueZ::OnRegisterAudioSink,
+                                  weak_ptr_factory_.GetWeakPtr(), callback,
+                                  error_callback, audio_sink),
+                       error_callback);
 }
 
-void BluetoothAdapterChromeOS::RegisterAdvertisement(
+void BluetoothAdapterBlueZ::RegisterAdvertisement(
     scoped_ptr<device::BluetoothAdvertisement::Data> advertisement_data,
     const CreateAdvertisementCallback& callback,
     const CreateAdvertisementErrorCallback& error_callback) {
-  scoped_refptr<BluetoothAdvertisementChromeOS> advertisement(
-      new BluetoothAdvertisementChromeOS(advertisement_data.Pass(), this));
+  scoped_refptr<BluetoothAdvertisementBlueZ> advertisement(
+      new BluetoothAdvertisementBlueZ(advertisement_data.Pass(), this));
   advertisement->Register(base::Bind(callback, advertisement), error_callback);
 }
 
-void BluetoothAdapterChromeOS::RemovePairingDelegateInternal(
+void BluetoothAdapterBlueZ::RemovePairingDelegateInternal(
     BluetoothDevice::PairingDelegate* pairing_delegate) {
   // Check if any device is using the pairing delegate.
   // If so, clear the pairing context which will make any responses no-ops.
   for (DevicesMap::const_iterator iter = devices_.begin();
        iter != devices_.end(); ++iter) {
-    BluetoothDeviceChromeOS* device_chromeos =
-        static_cast<BluetoothDeviceChromeOS*>(iter->second);
+    BluetoothDeviceBlueZ* device_bluez =
+        static_cast<BluetoothDeviceBlueZ*>(iter->second);
 
-    BluetoothPairingChromeOS* pairing = device_chromeos->GetPairing();
+    BluetoothPairingBlueZ* pairing = device_bluez->GetPairing();
     if (pairing && pairing->GetPairingDelegate() == pairing_delegate)
-      device_chromeos->EndPairing();
+      device_bluez->EndPairing();
   }
 }
 
-void BluetoothAdapterChromeOS::AdapterAdded(
-    const dbus::ObjectPath& object_path) {
+void BluetoothAdapterBlueZ::AdapterAdded(const dbus::ObjectPath& object_path) {
   // Set the adapter to the newly added adapter only if no adapter is present.
   if (!IsPresent())
     SetAdapter(object_path);
 }
 
-void BluetoothAdapterChromeOS::AdapterRemoved(
+void BluetoothAdapterBlueZ::AdapterRemoved(
     const dbus::ObjectPath& object_path) {
   if (object_path == object_path_)
     RemoveAdapter();
 }
 
-void BluetoothAdapterChromeOS::AdapterPropertyChanged(
+void BluetoothAdapterBlueZ::AdapterPropertyChanged(
     const dbus::ObjectPath& object_path,
     const std::string& property_name) {
   if (object_path != object_path_)
@@ -403,8 +396,7 @@
   }
 }
 
-void BluetoothAdapterChromeOS::DeviceAdded(
-  const dbus::ObjectPath& object_path) {
+void BluetoothAdapterBlueZ::DeviceAdded(const dbus::ObjectPath& object_path) {
   DCHECK(bluez::BluezDBusManager::Get());
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
@@ -413,42 +405,38 @@
     return;
   DCHECK(IsPresent());
 
-  BluetoothDeviceChromeOS* device_chromeos =
-      new BluetoothDeviceChromeOS(this,
-                                  object_path,
-                                  ui_task_runner_,
-                                  socket_thread_);
-  DCHECK(devices_.find(device_chromeos->GetAddress()) == devices_.end());
+  BluetoothDeviceBlueZ* device_bluez = new BluetoothDeviceBlueZ(
+      this, object_path, ui_task_runner_, socket_thread_);
+  DCHECK(devices_.find(device_bluez->GetAddress()) == devices_.end());
 
-  devices_.set(device_chromeos->GetAddress(),
-               scoped_ptr<BluetoothDevice>(device_chromeos));
+  devices_.set(device_bluez->GetAddress(),
+               scoped_ptr<BluetoothDevice>(device_bluez));
 
   FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
-                    DeviceAdded(this, device_chromeos));
+                    DeviceAdded(this, device_bluez));
 }
 
-void BluetoothAdapterChromeOS::DeviceRemoved(
-    const dbus::ObjectPath& object_path) {
+void BluetoothAdapterBlueZ::DeviceRemoved(const dbus::ObjectPath& object_path) {
   for (DevicesMap::const_iterator iter = devices_.begin();
        iter != devices_.end(); ++iter) {
-    BluetoothDeviceChromeOS* device_chromeos =
-        static_cast<BluetoothDeviceChromeOS*>(iter->second);
-    if (device_chromeos->object_path() == object_path) {
+    BluetoothDeviceBlueZ* device_bluez =
+        static_cast<BluetoothDeviceBlueZ*>(iter->second);
+    if (device_bluez->object_path() == object_path) {
       scoped_ptr<BluetoothDevice> scoped_device =
           devices_.take_and_erase(iter->first);
 
       FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
-                        DeviceRemoved(this, device_chromeos));
+                        DeviceRemoved(this, device_bluez));
       return;
     }
   }
 }
 
-void BluetoothAdapterChromeOS::DevicePropertyChanged(
+void BluetoothAdapterBlueZ::DevicePropertyChanged(
     const dbus::ObjectPath& object_path,
     const std::string& property_name) {
-  BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path);
-  if (!device_chromeos)
+  BluetoothDeviceBlueZ* device_bluez = GetDeviceWithPath(object_path);
+  if (!device_bluez)
     return;
 
   bluez::BluetoothDeviceClient::Properties* properties =
@@ -458,18 +446,18 @@
   if (property_name == properties->address.name()) {
     for (DevicesMap::iterator iter = devices_.begin(); iter != devices_.end();
          ++iter) {
-      if (iter->second->GetAddress() == device_chromeos->GetAddress()) {
+      if (iter->second->GetAddress() == device_bluez->GetAddress()) {
         std::string old_address = iter->first;
         VLOG(1) << "Device changed address, old: " << old_address
-                << " new: " << device_chromeos->GetAddress();
+                << " new: " << device_bluez->GetAddress();
         scoped_ptr<BluetoothDevice> scoped_device =
             devices_.take_and_erase(iter);
         ignore_result(scoped_device.release());
 
-        DCHECK(devices_.find(device_chromeos->GetAddress()) == devices_.end());
-        devices_.set(device_chromeos->GetAddress(),
-                     scoped_ptr<BluetoothDevice>(device_chromeos));
-        NotifyDeviceAddressChanged(device_chromeos, old_address);
+        DCHECK(devices_.find(device_bluez->GetAddress()) == devices_.end());
+        devices_.set(device_bluez->GetAddress(),
+                     scoped_ptr<BluetoothDevice>(device_bluez));
+        NotifyDeviceAddressChanged(device_bluez, old_address);
         break;
       }
     }
@@ -484,18 +472,18 @@
       property_name == properties->uuids.name() ||
       property_name == properties->rssi.name() ||
       property_name == properties->tx_power.name()) {
-    NotifyDeviceChanged(device_chromeos);
+    NotifyDeviceChanged(device_bluez);
   }
 
   if (property_name == properties->gatt_services.name()) {
-    NotifyGattServicesDiscovered(device_chromeos);
+    NotifyGattServicesDiscovered(device_bluez);
   }
 
   // When a device becomes paired, mark it as trusted so that the user does
   // not need to approve every incoming connection
   if (property_name == properties->paired.name() &&
       properties->paired.value() && !properties->trusted.value()) {
-    device_chromeos->SetTrusted();
+    device_bluez->SetTrusted();
   }
 
   // UMA connection counting
@@ -503,9 +491,9 @@
     // PlayStation joystick tries to reconnect after disconnection from USB.
     // If it is still not trusted, set it, so it becomes available on the
     // list of known devices.
-    if (properties->connected.value() && device_chromeos->IsTrustable() &&
+    if (properties->connected.value() && device_bluez->IsTrustable() &&
         !properties->trusted.value())
-      device_chromeos->SetTrusted();
+      device_bluez->SetTrusted();
 
     int count = 0;
 
@@ -519,11 +507,11 @@
   }
 }
 
-void BluetoothAdapterChromeOS::InputPropertyChanged(
+void BluetoothAdapterBlueZ::InputPropertyChanged(
     const dbus::ObjectPath& object_path,
     const std::string& property_name) {
-  BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path);
-  if (!device_chromeos)
+  BluetoothDeviceBlueZ* device_bluez = GetDeviceWithPath(object_path);
+  if (!device_bluez)
     return;
 
   bluez::BluetoothInputClient::Properties* properties =
@@ -534,11 +522,11 @@
   // BluetoothDevice::IsConnectable() property, as does a change in the
   // actual reconnect_mode property.
   if (!properties || property_name == properties->reconnect_mode.name()) {
-    NotifyDeviceChanged(device_chromeos);
+    NotifyDeviceChanged(device_bluez);
   }
 }
 
-void BluetoothAdapterChromeOS::Released() {
+void BluetoothAdapterBlueZ::Released() {
   VLOG(1) << "Release";
   if (!IsPresent())
     return;
@@ -548,14 +536,13 @@
   // capabilities. Nothing much to be done right now.
 }
 
-void BluetoothAdapterChromeOS::RequestPinCode(
-    const dbus::ObjectPath& device_path,
-    const PinCodeCallback& callback) {
+void BluetoothAdapterBlueZ::RequestPinCode(const dbus::ObjectPath& device_path,
+                                           const PinCodeCallback& callback) {
   DCHECK(IsPresent());
   DCHECK(agent_.get());
   VLOG(1) << device_path.value() << ": RequestPinCode";
 
-  BluetoothPairingChromeOS* pairing = GetPairing(device_path);
+  BluetoothPairingBlueZ* pairing = GetPairing(device_path);
   if (!pairing) {
     callback.Run(REJECTED, "");
     return;
@@ -564,28 +551,26 @@
   pairing->RequestPinCode(callback);
 }
 
-void BluetoothAdapterChromeOS::DisplayPinCode(
-    const dbus::ObjectPath& device_path,
-    const std::string& pincode) {
+void BluetoothAdapterBlueZ::DisplayPinCode(const dbus::ObjectPath& device_path,
+                                           const std::string& pincode) {
   DCHECK(IsPresent());
   DCHECK(agent_.get());
   VLOG(1) << device_path.value() << ": DisplayPinCode: " << pincode;
 
-  BluetoothPairingChromeOS* pairing = GetPairing(device_path);
+  BluetoothPairingBlueZ* pairing = GetPairing(device_path);
   if (!pairing)
     return;
 
   pairing->DisplayPinCode(pincode);
 }
 
-void BluetoothAdapterChromeOS::RequestPasskey(
-    const dbus::ObjectPath& device_path,
-    const PasskeyCallback& callback) {
+void BluetoothAdapterBlueZ::RequestPasskey(const dbus::ObjectPath& device_path,
+                                           const PasskeyCallback& callback) {
   DCHECK(IsPresent());
   DCHECK(agent_.get());
   VLOG(1) << device_path.value() << ": RequestPasskey";
 
-  BluetoothPairingChromeOS* pairing = GetPairing(device_path);
+  BluetoothPairingBlueZ* pairing = GetPairing(device_path);
   if (!pairing) {
     callback.Run(REJECTED, 0);
     return;
@@ -594,16 +579,15 @@
   pairing->RequestPasskey(callback);
 }
 
-void BluetoothAdapterChromeOS::DisplayPasskey(
-    const dbus::ObjectPath& device_path,
-    uint32 passkey,
-    uint16 entered) {
+void BluetoothAdapterBlueZ::DisplayPasskey(const dbus::ObjectPath& device_path,
+                                           uint32 passkey,
+                                           uint16 entered) {
   DCHECK(IsPresent());
   DCHECK(agent_.get());
-  VLOG(1) << device_path.value() << ": DisplayPasskey: " << passkey
-          << " (" << entered << " entered)";
+  VLOG(1) << device_path.value() << ": DisplayPasskey: " << passkey << " ("
+          << entered << " entered)";
 
-  BluetoothPairingChromeOS* pairing = GetPairing(device_path);
+  BluetoothPairingBlueZ* pairing = GetPairing(device_path);
   if (!pairing)
     return;
 
@@ -613,7 +597,7 @@
   pairing->KeysEntered(entered);
 }
 
-void BluetoothAdapterChromeOS::RequestConfirmation(
+void BluetoothAdapterBlueZ::RequestConfirmation(
     const dbus::ObjectPath& device_path,
     uint32 passkey,
     const ConfirmationCallback& callback) {
@@ -621,7 +605,7 @@
   DCHECK(agent_.get());
   VLOG(1) << device_path.value() << ": RequestConfirmation: " << passkey;
 
-  BluetoothPairingChromeOS* pairing = GetPairing(device_path);
+  BluetoothPairingBlueZ* pairing = GetPairing(device_path);
   if (!pairing) {
     callback.Run(REJECTED);
     return;
@@ -630,14 +614,14 @@
   pairing->RequestConfirmation(passkey, callback);
 }
 
-void BluetoothAdapterChromeOS::RequestAuthorization(
+void BluetoothAdapterBlueZ::RequestAuthorization(
     const dbus::ObjectPath& device_path,
     const ConfirmationCallback& callback) {
   DCHECK(IsPresent());
   DCHECK(agent_.get());
   VLOG(1) << device_path.value() << ": RequestAuthorization";
 
-  BluetoothPairingChromeOS* pairing = GetPairing(device_path);
+  BluetoothPairingBlueZ* pairing = GetPairing(device_path);
   if (!pairing) {
     callback.Run(REJECTED);
     return;
@@ -646,7 +630,7 @@
   pairing->RequestAuthorization(callback);
 }
 
-void BluetoothAdapterChromeOS::AuthorizeService(
+void BluetoothAdapterBlueZ::AuthorizeService(
     const dbus::ObjectPath& device_path,
     const std::string& uuid,
     const ConfirmationCallback& callback) {
@@ -654,8 +638,8 @@
   DCHECK(agent_.get());
   VLOG(1) << device_path.value() << ": AuthorizeService: " << uuid;
 
-  BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(device_path);
-  if (!device_chromeos) {
+  BluetoothDeviceBlueZ* device_bluez = GetDeviceWithPath(device_path);
+  if (!device_bluez) {
     callback.Run(CANCELLED);
     return;
   }
@@ -664,7 +648,7 @@
   // method call would ever be called is in the case of a race condition where
   // our "Set('Trusted', true)" method call is still pending in the Bluetooth
   // daemon because it's busy handling the incoming connection.
-  if (device_chromeos->IsPaired()) {
+  if (device_bluez->IsPaired()) {
     callback.Run(SUCCESS);
     return;
   }
@@ -672,52 +656,52 @@
   // TODO(keybuk): reject service authorizations when not paired, determine
   // whether this is acceptable long-term.
   LOG(WARNING) << "Rejecting service connection from unpaired device "
-               << device_chromeos->GetAddress() << " for UUID " << uuid;
+               << device_bluez->GetAddress() << " for UUID " << uuid;
   callback.Run(REJECTED);
 }
 
-void BluetoothAdapterChromeOS::Cancel() {
+void BluetoothAdapterBlueZ::Cancel() {
   DCHECK(IsPresent());
   DCHECK(agent_.get());
   VLOG(1) << "Cancel";
 }
 
-void BluetoothAdapterChromeOS::OnRegisterAgent() {
+void BluetoothAdapterBlueZ::OnRegisterAgent() {
   VLOG(1) << "Pairing agent registered, requesting to be made default";
 
   bluez::BluezDBusManager::Get()
       ->GetBluetoothAgentManagerClient()
       ->RequestDefaultAgent(
           dbus::ObjectPath(kAgentPath),
-          base::Bind(&BluetoothAdapterChromeOS::OnRequestDefaultAgent,
+          base::Bind(&BluetoothAdapterBlueZ::OnRequestDefaultAgent,
                      weak_ptr_factory_.GetWeakPtr()),
-          base::Bind(&BluetoothAdapterChromeOS::OnRequestDefaultAgentError,
+          base::Bind(&BluetoothAdapterBlueZ::OnRequestDefaultAgentError,
                      weak_ptr_factory_.GetWeakPtr()));
 }
 
-void BluetoothAdapterChromeOS::OnRegisterAgentError(
+void BluetoothAdapterBlueZ::OnRegisterAgentError(
     const std::string& error_name,
     const std::string& error_message) {
   // Our agent being already registered isn't an error.
   if (error_name == bluetooth_agent_manager::kErrorAlreadyExists)
     return;
 
-  LOG(WARNING) << ": Failed to register pairing agent: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << ": Failed to register pairing agent: " << error_name << ": "
+               << error_message;
 }
 
-void BluetoothAdapterChromeOS::OnRequestDefaultAgent() {
+void BluetoothAdapterBlueZ::OnRequestDefaultAgent() {
   VLOG(1) << "Pairing agent now default";
 }
 
-void BluetoothAdapterChromeOS::OnRequestDefaultAgentError(
+void BluetoothAdapterBlueZ::OnRequestDefaultAgentError(
     const std::string& error_name,
     const std::string& error_message) {
-  LOG(WARNING) << ": Failed to make pairing agent default: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << ": Failed to make pairing agent default: " << error_name
+               << ": " << error_message;
 }
 
-void BluetoothAdapterChromeOS::OnRegisterAudioSink(
+void BluetoothAdapterBlueZ::OnRegisterAudioSink(
     const device::BluetoothAdapter::AcquiredCallback& callback,
     const device::BluetoothAudioSink::ErrorCallback& error_callback,
     scoped_refptr<BluetoothAudioSink> audio_sink) {
@@ -730,34 +714,33 @@
   callback.Run(audio_sink);
 }
 
-BluetoothDeviceChromeOS*
-BluetoothAdapterChromeOS::GetDeviceWithPath(
+BluetoothDeviceBlueZ* BluetoothAdapterBlueZ::GetDeviceWithPath(
     const dbus::ObjectPath& object_path) {
   if (!IsPresent())
     return nullptr;
 
   for (DevicesMap::const_iterator iter = devices_.begin();
        iter != devices_.end(); ++iter) {
-    BluetoothDeviceChromeOS* device_chromeos =
-        static_cast<BluetoothDeviceChromeOS*>(iter->second);
-    if (device_chromeos->object_path() == object_path)
-      return device_chromeos;
+    BluetoothDeviceBlueZ* device_bluez =
+        static_cast<BluetoothDeviceBlueZ*>(iter->second);
+    if (device_bluez->object_path() == object_path)
+      return device_bluez;
   }
 
   return nullptr;
 }
 
-BluetoothPairingChromeOS* BluetoothAdapterChromeOS::GetPairing(
+BluetoothPairingBlueZ* BluetoothAdapterBlueZ::GetPairing(
     const dbus::ObjectPath& object_path) {
   DCHECK(IsPresent());
-  BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path);
-  if (!device_chromeos) {
+  BluetoothDeviceBlueZ* device_bluez = GetDeviceWithPath(object_path);
+  if (!device_bluez) {
     LOG(WARNING) << "Pairing Agent request for unknown device: "
                  << object_path.value();
     return nullptr;
   }
 
-  BluetoothPairingChromeOS* pairing = device_chromeos->GetPairing();
+  BluetoothPairingBlueZ* pairing = device_bluez->GetPairing();
   if (pairing)
     return pairing;
 
@@ -767,10 +750,10 @@
   if (!pairing_delegate)
     return nullptr;
 
-  return device_chromeos->BeginPairing(pairing_delegate);
+  return device_bluez->BeginPairing(pairing_delegate);
 }
 
-void BluetoothAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) {
+void BluetoothAdapterBlueZ::SetAdapter(const dbus::ObjectPath& object_path) {
   DCHECK(!IsPresent());
   DCHECK(!dbus_is_shutdown_);
   object_path_ = object_path;
@@ -780,13 +763,12 @@
   VLOG(1) << "Registering pairing agent";
   bluez::BluezDBusManager::Get()
       ->GetBluetoothAgentManagerClient()
-      ->RegisterAgent(
-          dbus::ObjectPath(kAgentPath),
-          bluetooth_agent_manager::kKeyboardDisplayCapability,
-          base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent,
-                     weak_ptr_factory_.GetWeakPtr()),
-          base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError,
-                     weak_ptr_factory_.GetWeakPtr()));
+      ->RegisterAgent(dbus::ObjectPath(kAgentPath),
+                      bluetooth_agent_manager::kKeyboardDisplayCapability,
+                      base::Bind(&BluetoothAdapterBlueZ::OnRegisterAgent,
+                                 weak_ptr_factory_.GetWeakPtr()),
+                      base::Bind(&BluetoothAdapterBlueZ::OnRegisterAgentError,
+                                 weak_ptr_factory_.GetWeakPtr()));
 
   SetDefaultAdapterName();
 
@@ -815,32 +797,36 @@
   }
 }
 
-void BluetoothAdapterChromeOS::SetDefaultAdapterName() {
+void BluetoothAdapterBlueZ::SetDefaultAdapterName() {
   DCHECK(IsPresent());
 
   std::string alias;
+#if defined(OS_CHROMEOS)
   switch (chromeos::GetDeviceType()) {
-    case DeviceType::kChromebase:
+    case chromeos::DeviceType::kChromebase:
       alias = "Chromebase";
       break;
-    case DeviceType::kChromebit:
+    case chromeos::DeviceType::kChromebit:
       alias = "Chromebit";
       break;
-    case DeviceType::kChromebook:
+    case chromeos::DeviceType::kChromebook:
       alias = "Chromebook";
       break;
-    case DeviceType::kChromebox:
+    case chromeos::DeviceType::kChromebox:
       alias = "Chromebox";
       break;
-    case DeviceType::kUnknown:
+    case chromeos::DeviceType::kUnknown:
       alias = "Chromebook";
       break;
   }
+#elif defined(OS_LINUX)
+  alias = "ChromeLinux";
+#endif
 
   SetName(alias, base::Bind(&base::DoNothing), base::Bind(&base::DoNothing));
 }
 
-void BluetoothAdapterChromeOS::RemoveAdapter() {
+void BluetoothAdapterBlueZ::RemoveAdapter() {
   DCHECK(IsPresent());
   VLOG(1) << object_path_.value() << ": adapter removed.";
 
@@ -872,18 +858,17 @@
   PresentChanged(false);
 }
 
-void BluetoothAdapterChromeOS::PoweredChanged(bool powered) {
+void BluetoothAdapterBlueZ::PoweredChanged(bool powered) {
   FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     AdapterPoweredChanged(this, powered));
 }
 
-void BluetoothAdapterChromeOS::DiscoverableChanged(bool discoverable) {
+void BluetoothAdapterBlueZ::DiscoverableChanged(bool discoverable) {
   FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     AdapterDiscoverableChanged(this, discoverable));
 }
 
-void BluetoothAdapterChromeOS::DiscoveringChanged(
-    bool discovering) {
+void BluetoothAdapterBlueZ::DiscoveringChanged(bool discovering) {
   // If the adapter stopped discovery due to a reason other than a request by
   // us, reset the count to 0.
   VLOG(1) << "Discovering changed: " << discovering;
@@ -897,13 +882,12 @@
                     AdapterDiscoveringChanged(this, discovering));
 }
 
-void BluetoothAdapterChromeOS::PresentChanged(bool present) {
+void BluetoothAdapterBlueZ::PresentChanged(bool present) {
   FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     AdapterPresentChanged(this, present));
 }
 
-void BluetoothAdapterChromeOS::NotifyDeviceChanged(
-    BluetoothDeviceChromeOS* device) {
+void BluetoothAdapterBlueZ::NotifyDeviceChanged(BluetoothDeviceBlueZ* device) {
   DCHECK(device);
   DCHECK(device->adapter_ == this);
 
@@ -911,8 +895,8 @@
                     DeviceChanged(this, device));
 }
 
-void BluetoothAdapterChromeOS::NotifyDeviceAddressChanged(
-    BluetoothDeviceChromeOS* device,
+void BluetoothAdapterBlueZ::NotifyDeviceAddressChanged(
+    BluetoothDeviceBlueZ* device,
     const std::string& old_address) {
   DCHECK(device->adapter_ == this);
 
@@ -920,126 +904,120 @@
                     DeviceAddressChanged(this, device, old_address));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattServiceAdded(
-    BluetoothRemoteGattServiceChromeOS* service) {
+void BluetoothAdapterBlueZ::NotifyGattServiceAdded(
+    BluetoothRemoteGattServiceBlueZ* service) {
   DCHECK_EQ(service->GetAdapter(), this);
-  DCHECK_EQ(
-      static_cast<BluetoothDeviceChromeOS*>(service->GetDevice())->adapter_,
-      this);
+  DCHECK_EQ(static_cast<BluetoothDeviceBlueZ*>(service->GetDevice())->adapter_,
+            this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattServiceAdded(this, service->GetDevice(), service));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattServiceRemoved(
-    BluetoothRemoteGattServiceChromeOS* service) {
+void BluetoothAdapterBlueZ::NotifyGattServiceRemoved(
+    BluetoothRemoteGattServiceBlueZ* service) {
   DCHECK_EQ(service->GetAdapter(), this);
-  DCHECK_EQ(
-      static_cast<BluetoothDeviceChromeOS*>(service->GetDevice())->adapter_,
-      this);
+  DCHECK_EQ(static_cast<BluetoothDeviceBlueZ*>(service->GetDevice())->adapter_,
+            this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattServiceRemoved(this, service->GetDevice(), service));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattServiceChanged(
-    BluetoothRemoteGattServiceChromeOS* service) {
+void BluetoothAdapterBlueZ::NotifyGattServiceChanged(
+    BluetoothRemoteGattServiceBlueZ* service) {
   DCHECK_EQ(service->GetAdapter(), this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattServiceChanged(this, service));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattServicesDiscovered(
-    BluetoothDeviceChromeOS* device) {
+void BluetoothAdapterBlueZ::NotifyGattServicesDiscovered(
+    BluetoothDeviceBlueZ* device) {
   DCHECK(device->adapter_ == this);
 
   FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattServicesDiscovered(this, device));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattDiscoveryComplete(
-    BluetoothRemoteGattServiceChromeOS* service) {
+void BluetoothAdapterBlueZ::NotifyGattDiscoveryComplete(
+    BluetoothRemoteGattServiceBlueZ* service) {
   DCHECK_EQ(service->GetAdapter(), this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattDiscoveryCompleteForService(this, service));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattCharacteristicAdded(
-    BluetoothRemoteGattCharacteristicChromeOS* characteristic) {
-  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>(
-                characteristic->GetService())->GetAdapter(),
+void BluetoothAdapterBlueZ::NotifyGattCharacteristicAdded(
+    BluetoothRemoteGattCharacteristicBlueZ* characteristic) {
+  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>(
+                characteristic->GetService())
+                ->GetAdapter(),
             this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattCharacteristicAdded(this, characteristic));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattCharacteristicRemoved(
-    BluetoothRemoteGattCharacteristicChromeOS* characteristic) {
-  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>(
-                characteristic->GetService())->GetAdapter(),
+void BluetoothAdapterBlueZ::NotifyGattCharacteristicRemoved(
+    BluetoothRemoteGattCharacteristicBlueZ* characteristic) {
+  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>(
+                characteristic->GetService())
+                ->GetAdapter(),
             this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattCharacteristicRemoved(this, characteristic));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattDescriptorAdded(
-    BluetoothRemoteGattDescriptorChromeOS* descriptor) {
-  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>(
-                descriptor->GetCharacteristic()->GetService())->GetAdapter(),
+void BluetoothAdapterBlueZ::NotifyGattDescriptorAdded(
+    BluetoothRemoteGattDescriptorBlueZ* descriptor) {
+  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>(
+                descriptor->GetCharacteristic()->GetService())
+                ->GetAdapter(),
             this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattDescriptorAdded(this, descriptor));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattDescriptorRemoved(
-    BluetoothRemoteGattDescriptorChromeOS* descriptor) {
-  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>(
-                descriptor->GetCharacteristic()->GetService())->GetAdapter(),
+void BluetoothAdapterBlueZ::NotifyGattDescriptorRemoved(
+    BluetoothRemoteGattDescriptorBlueZ* descriptor) {
+  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>(
+                descriptor->GetCharacteristic()->GetService())
+                ->GetAdapter(),
             this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattDescriptorRemoved(this, descriptor));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattCharacteristicValueChanged(
-    BluetoothRemoteGattCharacteristicChromeOS* characteristic,
+void BluetoothAdapterBlueZ::NotifyGattCharacteristicValueChanged(
+    BluetoothRemoteGattCharacteristicBlueZ* characteristic,
     const std::vector<uint8>& value) {
-  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>(
-                characteristic->GetService())->GetAdapter(),
+  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>(
+                characteristic->GetService())
+                ->GetAdapter(),
             this);
 
   FOR_EACH_OBSERVER(
-      BluetoothAdapter::Observer,
-      observers_,
+      BluetoothAdapter::Observer, observers_,
       GattCharacteristicValueChanged(this, characteristic, value));
 }
 
-void BluetoothAdapterChromeOS::NotifyGattDescriptorValueChanged(
-    BluetoothRemoteGattDescriptorChromeOS* descriptor,
+void BluetoothAdapterBlueZ::NotifyGattDescriptorValueChanged(
+    BluetoothRemoteGattDescriptorBlueZ* descriptor,
     const std::vector<uint8>& value) {
-  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>(
-                descriptor->GetCharacteristic()->GetService())->GetAdapter(),
+  DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>(
+                descriptor->GetCharacteristic()->GetService())
+                ->GetAdapter(),
             this);
 
-  FOR_EACH_OBSERVER(BluetoothAdapter::Observer,
-                    observers_,
+  FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                     GattDescriptorValueChanged(this, descriptor, value));
 }
 
-void BluetoothAdapterChromeOS::UseProfile(
+void BluetoothAdapterBlueZ::UseProfile(
     const BluetoothUUID& uuid,
     const dbus::ObjectPath& device_path,
     const bluez::BluetoothProfileManagerClient::Options& options,
@@ -1063,32 +1041,31 @@
   }
 
   if (profile_queues_.find(uuid) == profile_queues_.end()) {
-    BluetoothAdapterProfileChromeOS::Register(
+    BluetoothAdapterProfileBlueZ::Register(
         uuid, options,
-        base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfile, this, uuid),
-        base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfileError, this,
-                   uuid));
+        base::Bind(&BluetoothAdapterBlueZ::OnRegisterProfile, this, uuid),
+        base::Bind(&BluetoothAdapterBlueZ::OnRegisterProfileError, this, uuid));
 
     profile_queues_[uuid] = new std::vector<RegisterProfileCompletionPair>();
   }
 
   profile_queues_[uuid]->push_back(std::make_pair(
-      base::Bind(&BluetoothAdapterChromeOS::SetProfileDelegate, this, uuid,
+      base::Bind(&BluetoothAdapterBlueZ::SetProfileDelegate, this, uuid,
                  device_path, delegate, success_callback, error_callback),
       error_callback));
 }
 
-void BluetoothAdapterChromeOS::ReleaseProfile(
+void BluetoothAdapterBlueZ::ReleaseProfile(
     const dbus::ObjectPath& device_path,
-    BluetoothAdapterProfileChromeOS* profile) {
+    BluetoothAdapterProfileBlueZ* profile) {
   VLOG(2) << "Releasing Profile: " << profile->uuid().canonical_value()
           << " from " << device_path.value();
   profile->RemoveDelegate(
-      device_path, base::Bind(&BluetoothAdapterChromeOS::RemoveProfile,
+      device_path, base::Bind(&BluetoothAdapterBlueZ::RemoveProfile,
                               weak_ptr_factory_.GetWeakPtr(), profile->uuid()));
 }
 
-void BluetoothAdapterChromeOS::RemoveProfile(const BluetoothUUID& uuid) {
+void BluetoothAdapterBlueZ::RemoveProfile(const BluetoothUUID& uuid) {
   VLOG(2) << "Remove Profile: " << uuid.canonical_value();
 
   if (profiles_.find(uuid) != profiles_.end()) {
@@ -1097,9 +1074,9 @@
   }
 }
 
-void BluetoothAdapterChromeOS::OnRegisterProfile(
+void BluetoothAdapterBlueZ::OnRegisterProfile(
     const BluetoothUUID& uuid,
-    scoped_ptr<BluetoothAdapterProfileChromeOS> profile) {
+    scoped_ptr<BluetoothAdapterProfileBlueZ> profile) {
   profiles_[uuid] = profile.release();
 
   if (profile_queues_.find(uuid) == profile_queues_.end())
@@ -1111,7 +1088,7 @@
   profile_queues_.erase(uuid);
 }
 
-void BluetoothAdapterChromeOS::SetProfileDelegate(
+void BluetoothAdapterBlueZ::SetProfileDelegate(
     const BluetoothUUID& uuid,
     const dbus::ObjectPath& device_path,
     bluez::BluetoothProfileServiceProvider::Delegate* delegate,
@@ -1130,12 +1107,13 @@
   error_callback.Run(bluetooth_agent_manager::kErrorAlreadyExists);
 }
 
-void BluetoothAdapterChromeOS::OnRegisterProfileError(
+void BluetoothAdapterBlueZ::OnRegisterProfileError(
     const BluetoothUUID& uuid,
     const std::string& error_name,
     const std::string& error_message) {
-  VLOG(2) << object_path_.value() << ": Failed to register profile: "
-          << error_name << ": " << error_message;
+  VLOG(2) << object_path_.value()
+          << ": Failed to register profile: " << error_name << ": "
+          << error_message;
   if (profile_queues_.find(uuid) == profile_queues_.end())
     return;
 
@@ -1146,7 +1124,7 @@
   profile_queues_.erase(uuid);
 }
 
-void BluetoothAdapterChromeOS::OnSetDiscoverable(
+void BluetoothAdapterBlueZ::OnSetDiscoverable(
     const base::Closure& callback,
     const ErrorCallback& error_callback,
     bool success) {
@@ -1162,11 +1140,11 @@
       ->GetProperties(object_path_)
       ->discoverable_timeout.Set(
           0,
-          base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted,
+          base::Bind(&BluetoothAdapterBlueZ::OnPropertyChangeCompleted,
                      weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
-void BluetoothAdapterChromeOS::OnPropertyChangeCompleted(
+void BluetoothAdapterBlueZ::OnPropertyChangeCompleted(
     const base::Closure& callback,
     const ErrorCallback& error_callback,
     bool success) {
@@ -1177,7 +1155,7 @@
   }
 }
 
-void BluetoothAdapterChromeOS::AddDiscoverySession(
+void BluetoothAdapterBlueZ::AddDiscoverySession(
     BluetoothDiscoveryFilter* discovery_filter,
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback) {
@@ -1220,9 +1198,9 @@
     df->CopyFrom(*discovery_filter);
     SetDiscoveryFilter(
         df.Pass(),
-        base::Bind(&BluetoothAdapterChromeOS::OnPreSetDiscoveryFilter,
+        base::Bind(&BluetoothAdapterBlueZ::OnPreSetDiscoveryFilter,
                    weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
-        base::Bind(&BluetoothAdapterChromeOS::OnPreSetDiscoveryFilterError,
+        base::Bind(&BluetoothAdapterBlueZ::OnPreSetDiscoveryFilterError,
                    weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
     return;
   } else {
@@ -1233,13 +1211,13 @@
   discovery_request_pending_ = true;
   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery(
       object_path_,
-      base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery,
+      base::Bind(&BluetoothAdapterBlueZ::OnStartDiscovery,
                  weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
-      base::Bind(&BluetoothAdapterChromeOS::OnStartDiscoveryError,
+      base::Bind(&BluetoothAdapterBlueZ::OnStartDiscoveryError,
                  weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
-void BluetoothAdapterChromeOS::RemoveDiscoverySession(
+void BluetoothAdapterBlueZ::RemoveDiscoverySession(
     BluetoothDiscoveryFilter* discovery_filter,
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback) {
@@ -1286,13 +1264,13 @@
   DCHECK_EQ(num_discovery_sessions_, 1);
   discovery_request_pending_ = true;
   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StopDiscovery(
-      object_path_, base::Bind(&BluetoothAdapterChromeOS::OnStopDiscovery,
+      object_path_, base::Bind(&BluetoothAdapterBlueZ::OnStopDiscovery,
                                weak_ptr_factory_.GetWeakPtr(), callback),
-      base::Bind(&BluetoothAdapterChromeOS::OnStopDiscoveryError,
+      base::Bind(&BluetoothAdapterBlueZ::OnStopDiscoveryError,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothAdapterChromeOS::SetDiscoveryFilter(
+void BluetoothAdapterBlueZ::SetDiscoveryFilter(
     scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback) {
@@ -1357,13 +1335,13 @@
       ->GetBluetoothAdapterClient()
       ->SetDiscoveryFilter(
           object_path_, dbus_discovery_filter,
-          base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilter,
+          base::Bind(&BluetoothAdapterBlueZ::OnSetDiscoveryFilter,
                      weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
-          base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilterError,
+          base::Bind(&BluetoothAdapterBlueZ::OnSetDiscoveryFilterError,
                      weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
-void BluetoothAdapterChromeOS::OnStartDiscovery(
+void BluetoothAdapterBlueZ::OnStartDiscovery(
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback) {
   // Report success on the original request and increment the count.
@@ -1382,13 +1360,14 @@
   ProcessQueuedDiscoveryRequests();
 }
 
-void BluetoothAdapterChromeOS::OnStartDiscoveryError(
+void BluetoothAdapterBlueZ::OnStartDiscoveryError(
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
-  LOG(WARNING) << object_path_.value() << ": Failed to start discovery: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << object_path_.value()
+               << ": Failed to start discovery: " << error_name << ": "
+               << error_message;
 
   // Failed to start discovery. This can only happen if the count is at 0.
   DCHECK_EQ(num_discovery_sessions_, 0);
@@ -1411,7 +1390,7 @@
   ProcessQueuedDiscoveryRequests();
 }
 
-void BluetoothAdapterChromeOS::OnStopDiscovery(const base::Closure& callback) {
+void BluetoothAdapterBlueZ::OnStopDiscovery(const base::Closure& callback) {
   // Report success on the original request and decrement the count.
   VLOG(1) << __func__;
   DCHECK(discovery_request_pending_);
@@ -1426,12 +1405,13 @@
   ProcessQueuedDiscoveryRequests();
 }
 
-void BluetoothAdapterChromeOS::OnStopDiscoveryError(
+void BluetoothAdapterBlueZ::OnStopDiscoveryError(
     const DiscoverySessionErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
-  LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << object_path_.value()
+               << ": Failed to stop discovery: " << error_name << ": "
+               << error_message;
 
   // Failed to stop discovery. This can only happen if the count is at 1.
   DCHECK(discovery_request_pending_);
@@ -1443,7 +1423,7 @@
   ProcessQueuedDiscoveryRequests();
 }
 
-void BluetoothAdapterChromeOS::OnPreSetDiscoveryFilter(
+void BluetoothAdapterBlueZ::OnPreSetDiscoveryFilter(
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback) {
   // This is the first request to start device discovery.
@@ -1452,13 +1432,13 @@
 
   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery(
       object_path_,
-      base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery,
+      base::Bind(&BluetoothAdapterBlueZ::OnStartDiscovery,
                  weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
-      base::Bind(&BluetoothAdapterChromeOS::OnStartDiscoveryError,
+      base::Bind(&BluetoothAdapterBlueZ::OnStartDiscoveryError,
                  weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
 }
 
-void BluetoothAdapterChromeOS::OnPreSetDiscoveryFilterError(
+void BluetoothAdapterBlueZ::OnPreSetDiscoveryFilterError(
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback,
     UMABluetoothDiscoverySessionOutcome outcome) {
@@ -1476,7 +1456,7 @@
   ProcessQueuedDiscoveryRequests();
 }
 
-void BluetoothAdapterChromeOS::OnSetDiscoveryFilter(
+void BluetoothAdapterBlueZ::OnSetDiscoveryFilter(
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback) {
   // Report success on the original request and increment the count.
@@ -1488,7 +1468,7 @@
   }
 }
 
-void BluetoothAdapterChromeOS::OnSetDiscoveryFilterError(
+void BluetoothAdapterBlueZ::OnSetDiscoveryFilterError(
     const base::Closure& callback,
     const DiscoverySessionErrorCallback& error_callback,
     const std::string& error_name,
@@ -1504,7 +1484,7 @@
     // SetDiscoveryFilter when the controller doesn't support the requested
     // transport.
     outcome = UMABluetoothDiscoverySessionOutcome::
-        CHROMEOS_DBUS_FAILED_MAYBE_UNSUPPORTED_TRANSPORT;
+        BLUEZ_DBUS_FAILED_MAYBE_UNSUPPORTED_TRANSPORT;
   }
   error_callback.Run(outcome);
 
@@ -1512,7 +1492,7 @@
   ProcessQueuedDiscoveryRequests();
 }
 
-void BluetoothAdapterChromeOS::ProcessQueuedDiscoveryRequests() {
+void BluetoothAdapterBlueZ::ProcessQueuedDiscoveryRequests() {
   while (!discovery_request_queue_.empty()) {
     VLOG(1) << "Process queued discovery request.";
     DiscoveryParamTuple params = discovery_request_queue_.front();
@@ -1528,4 +1508,4 @@
   }
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_bluez.h
similarity index 83%
rename from device/bluetooth/bluetooth_adapter_chromeos.h
rename to device/bluetooth/bluetooth_adapter_bluez.h
index 53b271f6..e5bf146 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_bluez.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_BLUEZ_H_
 
 #include <map>
 #include <queue>
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
@@ -33,17 +34,17 @@
 class BluetoothSocketThread;
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothChromeOSTest;
-class BluetoothAdapterProfileChromeOS;
-class BluetoothDeviceChromeOS;
-class BluetoothPairingChromeOS;
-class BluetoothRemoteGattCharacteristicChromeOS;
-class BluetoothRemoteGattDescriptorChromeOS;
-class BluetoothRemoteGattServiceChromeOS;
+class BluetoothBlueZTest;
+class BluetoothAdapterProfileBlueZ;
+class BluetoothDeviceBlueZ;
+class BluetoothPairingBlueZ;
+class BluetoothRemoteGattCharacteristicBlueZ;
+class BluetoothRemoteGattDescriptorBlueZ;
+class BluetoothRemoteGattServiceBlueZ;
 
-// The BluetoothAdapterChromeOS class implements BluetoothAdapter for the
+// The BluetoothAdapterBlueZ class implements BluetoothAdapter for the
 // Chrome OS platform.
 //
 // All methods are called from the dbus origin / UI thread and are generally
@@ -52,13 +53,13 @@
 // This class interacts with sockets using the BluetoothSocketThread to ensure
 // single-threaded calls, and posts tasks to the UI thread.
 //
-// Methods tolerate a shutdown scenario where BluetoothAdapterChromeOS::Shutdown
+// Methods tolerate a shutdown scenario where BluetoothAdapterBlueZ::Shutdown
 // causes IsPresent to return false just before the dbus system is shutdown but
-// while references to the BluetoothAdapterChromeOS object still exists.
+// while references to the BluetoothAdapterBlueZ object still exists.
 //
 // When adding methods to this class verify shutdown behavior in
-// BluetoothChromeOSTest, Shutdown.
-class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
+// BluetoothBlueZTest, Shutdown.
+class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterBlueZ
     : public device::BluetoothAdapter,
       public bluez::BluetoothAdapterClient::Observer,
       public bluez::BluetoothDeviceClient::Observer,
@@ -67,7 +68,7 @@
  public:
   typedef base::Callback<void(const std::string& error_message)>
       ErrorCompletionCallback;
-  typedef base::Callback<void(BluetoothAdapterProfileChromeOS* profile)>
+  typedef base::Callback<void(BluetoothAdapterProfileBlueZ* profile)>
       ProfileRegisteredCallback;
 
   static base::WeakPtr<BluetoothAdapter> CreateAdapter();
@@ -112,37 +113,36 @@
 
   // Locates the device object by object path (the devices map and
   // BluetoothDevice methods are by address).
-  BluetoothDeviceChromeOS* GetDeviceWithPath(
-      const dbus::ObjectPath& object_path);
+  BluetoothDeviceBlueZ* GetDeviceWithPath(const dbus::ObjectPath& object_path);
 
   // Announces to observers a change in device state that is not reflected by
   // its D-Bus properties. |device| is owned by the caller and cannot be NULL.
-  void NotifyDeviceChanged(BluetoothDeviceChromeOS* device);
+  void NotifyDeviceChanged(BluetoothDeviceBlueZ* device);
 
   // Announce to observers a device address change.
-  void NotifyDeviceAddressChanged(BluetoothDeviceChromeOS* device,
+  void NotifyDeviceAddressChanged(BluetoothDeviceBlueZ* device,
                                   const std::string& old_address);
 
   // The following methods are used to send various GATT observer events to
   // observers.
-  void NotifyGattServiceAdded(BluetoothRemoteGattServiceChromeOS* service);
-  void NotifyGattServiceRemoved(BluetoothRemoteGattServiceChromeOS* service);
-  void NotifyGattServiceChanged(BluetoothRemoteGattServiceChromeOS* service);
-  void NotifyGattServicesDiscovered(BluetoothDeviceChromeOS* device);
-  void NotifyGattDiscoveryComplete(BluetoothRemoteGattServiceChromeOS* service);
+  void NotifyGattServiceAdded(BluetoothRemoteGattServiceBlueZ* service);
+  void NotifyGattServiceRemoved(BluetoothRemoteGattServiceBlueZ* service);
+  void NotifyGattServiceChanged(BluetoothRemoteGattServiceBlueZ* service);
+  void NotifyGattServicesDiscovered(BluetoothDeviceBlueZ* device);
+  void NotifyGattDiscoveryComplete(BluetoothRemoteGattServiceBlueZ* service);
   void NotifyGattCharacteristicAdded(
-      BluetoothRemoteGattCharacteristicChromeOS* characteristic);
+      BluetoothRemoteGattCharacteristicBlueZ* characteristic);
   void NotifyGattCharacteristicRemoved(
-      BluetoothRemoteGattCharacteristicChromeOS* characteristic);
+      BluetoothRemoteGattCharacteristicBlueZ* characteristic);
   void NotifyGattDescriptorAdded(
-      BluetoothRemoteGattDescriptorChromeOS* descriptor);
+      BluetoothRemoteGattDescriptorBlueZ* descriptor);
   void NotifyGattDescriptorRemoved(
-      BluetoothRemoteGattDescriptorChromeOS* descriptor);
+      BluetoothRemoteGattDescriptorBlueZ* descriptor);
   void NotifyGattCharacteristicValueChanged(
-      BluetoothRemoteGattCharacteristicChromeOS* characteristic,
+      BluetoothRemoteGattCharacteristicBlueZ* characteristic,
       const std::vector<uint8>& value);
   void NotifyGattDescriptorValueChanged(
-      BluetoothRemoteGattDescriptorChromeOS* descriptor,
+      BluetoothRemoteGattDescriptorBlueZ* descriptor,
       const std::vector<uint8>& value);
 
   // Returns the object path of the adapter.
@@ -153,7 +153,7 @@
   // If |device_path| is the empty string, incoming connections will be
   // assigned to |delegate|.  When the profile is
   // successfully registered, |success_callback| will be called with a pointer
-  // to the profile which is managed by BluetoothAdapterChromeOS.  On failure,
+  // to the profile which is managed by BluetoothAdapterBlueZ.  On failure,
   // |error_callback| will be called.
   void UseProfile(const device::BluetoothUUID& uuid,
                   const dbus::ObjectPath& device_path,
@@ -164,7 +164,7 @@
 
   // Release use of a profile by a device.
   void ReleaseProfile(const dbus::ObjectPath& device_path,
-                      BluetoothAdapterProfileChromeOS* profile);
+                      BluetoothAdapterProfileBlueZ* profile);
 
  protected:
   // BluetoothAdapter:
@@ -172,12 +172,12 @@
       device::BluetoothDevice::PairingDelegate* pairing_delegate) override;
 
  private:
-  friend class BluetoothChromeOSTest;
-  friend class BluetoothChromeOSTest_Shutdown_Test;
-  friend class BluetoothChromeOSTest_Shutdown_OnStartDiscovery_Test;
-  friend class BluetoothChromeOSTest_Shutdown_OnStartDiscoveryError_Test;
-  friend class BluetoothChromeOSTest_Shutdown_OnStopDiscovery_Test;
-  friend class BluetoothChromeOSTest_Shutdown_OnStopDiscoveryError_Test;
+  friend class BluetoothBlueZTest;
+  friend class BluetoothBlueZTest_Shutdown_Test;
+  friend class BluetoothBlueZTest_Shutdown_OnStartDiscovery_Test;
+  friend class BluetoothBlueZTest_Shutdown_OnStartDiscoveryError_Test;
+  friend class BluetoothBlueZTest_Shutdown_OnStopDiscovery_Test;
+  friend class BluetoothBlueZTest_Shutdown_OnStopDiscoveryError_Test;
 
   // typedef for callback parameters that are passed to AddDiscoverySession
   // and RemoveDiscoverySession. This is used to queue incoming requests while
@@ -191,8 +191,8 @@
   typedef std::pair<base::Closure, ErrorCompletionCallback>
       RegisterProfileCompletionPair;
 
-  BluetoothAdapterChromeOS();
-  ~BluetoothAdapterChromeOS() override;
+  BluetoothAdapterBlueZ();
+  ~BluetoothAdapterBlueZ() override;
 
   // bluez::BluetoothAdapterClient::Observer override.
   void AdapterAdded(const dbus::ObjectPath& object_path) override;
@@ -243,19 +243,19 @@
   void OnRequestDefaultAgentError(const std::string& error_name,
                                   const std::string& error_message);
 
-  // Called by BluetoothAudioSinkChromeOS on completion of registering an audio
+  // Called by BluetoothAudioSinkBlueZ on completion of registering an audio
   // sink.
   void OnRegisterAudioSink(
       const device::BluetoothAdapter::AcquiredCallback& callback,
       const device::BluetoothAudioSink::ErrorCallback& error_callback,
       scoped_refptr<device::BluetoothAudioSink> audio_sink);
 
-  // Internal method to obtain a BluetoothPairingChromeOS object for the device
+  // Internal method to obtain a BluetoothPairingBlueZ object for the device
   // with path |object_path|. Returns the existing pairing object if the device
   // already has one (usually an outgoing connection in progress) or a new
   // pairing object with the default pairing delegate if not. If no default
   // pairing object exists, NULL will be returned.
-  BluetoothPairingChromeOS* GetPairing(const dbus::ObjectPath& object_path);
+  BluetoothPairingBlueZ* GetPairing(const dbus::ObjectPath& object_path);
 
   // Set the tracked adapter to the one in |object_path|, this object will
   // subsequently operate on that adapter until it is removed.
@@ -331,7 +331,7 @@
 
   // Called by dbus:: on completion of the D-Bus method to register a profile.
   void OnRegisterProfile(const device::BluetoothUUID& uuid,
-                         scoped_ptr<BluetoothAdapterProfileChromeOS> profile);
+                         scoped_ptr<BluetoothAdapterProfileBlueZ> profile);
 
   void SetProfileDelegate(
       const device::BluetoothUUID& uuid,
@@ -343,7 +343,7 @@
                               const std::string& error_name,
                               const std::string& error_message);
 
-  // Called by BluetoothAdapterProfileChromeOS when no users of a profile
+  // Called by BluetoothAdapterProfileBlueZ when no users of a profile
   // remain.
   void RemoveProfile(const device::BluetoothUUID& uuid);
 
@@ -385,7 +385,7 @@
   scoped_refptr<device::BluetoothSocketThread> socket_thread_;
 
   // The profiles we have registered with the bluetooth daemon.
-  std::map<device::BluetoothUUID, BluetoothAdapterProfileChromeOS*> profiles_;
+  std::map<device::BluetoothUUID, BluetoothAdapterProfileBlueZ*> profiles_;
 
   // Queue of delegates waiting for a profile to register.
   std::map<device::BluetoothUUID, std::vector<RegisterProfileCompletionPair>*>
@@ -395,11 +395,11 @@
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothAdapterChromeOS> weak_ptr_factory_;
+  base::WeakPtrFactory<BluetoothAdapterBlueZ> weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_adapter_factory.cc b/device/bluetooth/bluetooth_adapter_factory.cc
index c3e6d5cff..9771439 100644
--- a/device/bluetooth/bluetooth_adapter_factory.cc
+++ b/device/bluetooth/bluetooth_adapter_factory.cc
@@ -12,8 +12,8 @@
 #include "base/memory/weak_ptr.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 
-#if defined(OS_CHROMEOS)
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #endif
 
 #if defined(OS_MACOSX)
@@ -62,6 +62,8 @@
   // instance even on platforms that would otherwise not support it.
   if (default_adapter.Get())
     return true;
+// Even though the adapter is available on Linux, we only want to use it for
+// the Chrome API, which is why defines(OS_LINUX) is missing from here.
 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(OS_WIN)
   return true;
 #elif defined(OS_MACOSX)
@@ -73,7 +75,12 @@
 
 // static
 void BluetoothAdapterFactory::GetAdapter(const AdapterCallback& callback) {
+// TODO(rkc): This is a very slight hack to allow us to be able to create
+// an adapter on Linux, 'without' exposing the adapter to all Bluetooth
+// services within the browser.
+#if !defined(OS_LINUX)
   DCHECK(IsBluetoothAdapterAvailable());
+#endif
 
 #if defined(OS_WIN)
   if (!default_adapter.Get()) {
@@ -98,7 +105,7 @@
 
 }
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // static
 void BluetoothAdapterFactory::Shutdown() {
   if (default_adapter.Get())
diff --git a/device/bluetooth/bluetooth_adapter_factory.h b/device/bluetooth/bluetooth_adapter_factory.h
index 3b11685..05e1d3d 100644
--- a/device/bluetooth/bluetooth_adapter_factory.h
+++ b/device/bluetooth/bluetooth_adapter_factory.h
@@ -29,7 +29,7 @@
   // use.
   static void GetAdapter(const AdapterCallback& callback);
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
   // Calls |BluetoothAdapter::Shutdown| on the adapter if
   // present.
   static void Shutdown();
diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos.cc b/device/bluetooth/bluetooth_adapter_profile_bluez.cc
similarity index 83%
rename from device/bluetooth/bluetooth_adapter_profile_chromeos.cc
rename to device/bluetooth/bluetooth_adapter_profile_bluez.cc
index 27779f28..845002bf 100644
--- a/device/bluetooth/bluetooth_adapter_profile_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_profile_bluez.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_profile_bluez.h"
 
 #include <string>
 
@@ -11,21 +11,21 @@
 #include "base/strings/string_util.h"
 #include "dbus/bus.h"
 #include "dbus/object_path.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 #include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
-namespace chromeos {
+namespace bluez {
 
 // static
-void BluetoothAdapterProfileChromeOS::Register(
+void BluetoothAdapterProfileBlueZ::Register(
     const device::BluetoothUUID& uuid,
     const bluez::BluetoothProfileManagerClient::Options& options,
     const ProfileRegisteredCallback& success_callback,
     const bluez::BluetoothProfileManagerClient::ErrorCallback& error_callback) {
-  scoped_ptr<BluetoothAdapterProfileChromeOS> profile(
-      new BluetoothAdapterProfileChromeOS(uuid));
+  scoped_ptr<BluetoothAdapterProfileBlueZ> profile(
+      new BluetoothAdapterProfileBlueZ(uuid));
 
   VLOG(1) << "Registering profile: " << profile->object_path().value();
   const dbus::ObjectPath& object_path = profile->object_path();
@@ -36,7 +36,7 @@
                         error_callback);
 }
 
-BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(
+BluetoothAdapterProfileBlueZ::BluetoothAdapterProfileBlueZ(
     const device::BluetoothUUID& uuid)
     : uuid_(uuid), weak_ptr_factory_(this) {
   std::string uuid_path;
@@ -50,10 +50,9 @@
   DCHECK(profile_.get());
 }
 
-BluetoothAdapterProfileChromeOS::~BluetoothAdapterProfileChromeOS() {
-}
+BluetoothAdapterProfileBlueZ::~BluetoothAdapterProfileBlueZ() {}
 
-bool BluetoothAdapterProfileChromeOS::SetDelegate(
+bool BluetoothAdapterProfileBlueZ::SetDelegate(
     const dbus::ObjectPath& device_path,
     bluez::BluetoothProfileServiceProvider::Delegate* delegate) {
   DCHECK(delegate);
@@ -68,7 +67,7 @@
   return true;
 }
 
-void BluetoothAdapterProfileChromeOS::RemoveDelegate(
+void BluetoothAdapterProfileBlueZ::RemoveDelegate(
     const dbus::ObjectPath& device_path,
     const base::Closure& unregistered_callback) {
   VLOG(1) << object_path_.value() << " dev " << device_path.value()
@@ -89,11 +88,11 @@
       ->GetBluetoothProfileManagerClient()
       ->UnregisterProfile(
           object_path_, unregistered_callback,
-          base::Bind(&BluetoothAdapterProfileChromeOS::OnUnregisterProfileError,
+          base::Bind(&BluetoothAdapterProfileBlueZ::OnUnregisterProfileError,
                      weak_ptr_factory_.GetWeakPtr(), unregistered_callback));
 }
 
-void BluetoothAdapterProfileChromeOS::OnUnregisterProfileError(
+void BluetoothAdapterProfileBlueZ::OnUnregisterProfileError(
     const base::Closure& unregistered_callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -105,11 +104,11 @@
 }
 
 // bluez::BluetoothProfileServiceProvider::Delegate:
-void BluetoothAdapterProfileChromeOS::Released() {
+void BluetoothAdapterProfileBlueZ::Released() {
   VLOG(1) << object_path_.value() << ": Release";
 }
 
-void BluetoothAdapterProfileChromeOS::NewConnection(
+void BluetoothAdapterProfileBlueZ::NewConnection(
     const dbus::ObjectPath& device_path,
     scoped_ptr<dbus::FileDescriptor> fd,
     const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
@@ -130,7 +129,7 @@
                                                    options, callback);
 }
 
-void BluetoothAdapterProfileChromeOS::RequestDisconnection(
+void BluetoothAdapterProfileBlueZ::RequestDisconnection(
     const dbus::ObjectPath& device_path,
     const ConfirmationCallback& callback) {
   dbus::ObjectPath delegate_path = device_path;
@@ -148,7 +147,7 @@
                                                           callback);
 }
 
-void BluetoothAdapterProfileChromeOS::Cancel() {
+void BluetoothAdapterProfileBlueZ::Cancel() {
   // Cancel() should only go to a delegate accepting connections.
   if (delegates_.find("") == delegates_.end()) {
     VLOG(1) << object_path_.value() << ": Cancel with no delegate!";
@@ -158,4 +157,4 @@
   delegates_[""]->Cancel();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos.h b/device/bluetooth/bluetooth_adapter_profile_bluez.h
similarity index 80%
rename from device/bluetooth/bluetooth_adapter_profile_chromeos.h
rename to device/bluetooth/bluetooth_adapter_profile_bluez.h
index 35971e8..5382c8f 100644
--- a/device/bluetooth/bluetooth_adapter_profile_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_profile_bluez.h
@@ -2,11 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_PROFILE_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_PROFILE_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_PROFILE_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_PROFILE_BLUEZ_H_
 
+#include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #include "device/bluetooth/bluetooth_export.h"
 #include "device/bluetooth/dbus/bluetooth_profile_manager_client.h"
 #include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
@@ -15,9 +16,9 @@
 class BluetoothUUID;
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
-// The BluetoothAdapterProfileChromeOS class implements a multiplexing
+// The BluetoothAdapterProfileBlueZ class implements a multiplexing
 // profile for custom Bluetooth services managed by a BluetoothAdapter.
 // Maintains a list of delegates which may serve the profile.
 // One delegate is allowed for each device.
@@ -25,13 +26,13 @@
 // This class is not thread-safe, but is only called from the dbus origin
 // thread.
 //
-// BluetoothAdapterProfileChromeOS objects are owned by the
-// BluetoothAdapterChromeOS and allocated through Register()
-class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS
+// BluetoothAdapterProfileBlueZ objects are owned by the
+// BluetoothAdapterBlueZ and allocated through Register()
+class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileBlueZ
     : public bluez::BluetoothProfileServiceProvider::Delegate {
  public:
-  typedef base::Callback<void(scoped_ptr<BluetoothAdapterProfileChromeOS>
-                                  profile)> ProfileRegisteredCallback;
+  typedef base::Callback<void(scoped_ptr<BluetoothAdapterProfileBlueZ> profile)>
+      ProfileRegisteredCallback;
 
   // Registers a profile with the BlueZ server for |uuid| with the
   // options |options|.  |success_callback| is provided with a newly
@@ -44,7 +45,7 @@
       const bluez::BluetoothProfileManagerClient::ErrorCallback&
           error_callback);
 
-  ~BluetoothAdapterProfileChromeOS() override;
+  ~BluetoothAdapterProfileBlueZ() override;
 
   // The object path of the profile.
   const dbus::ObjectPath& object_path() const { return object_path_; }
@@ -68,7 +69,7 @@
   size_t DelegateCount() const { return delegates_.size(); }
 
  private:
-  BluetoothAdapterProfileChromeOS(const device::BluetoothUUID& uuid);
+  BluetoothAdapterProfileBlueZ(const device::BluetoothUUID& uuid);
 
   // bluez::BluetoothProfileServiceProvider::Delegate:
   void Released() override;
@@ -101,11 +102,11 @@
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothAdapterProfileChromeOS> weak_ptr_factory_;
+  base::WeakPtrFactory<BluetoothAdapterProfileBlueZ> weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterProfileChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterProfileBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_PROFILE_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_PROFILE_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc b/device/bluetooth/bluetooth_adapter_profile_bluez_unittest.cc
similarity index 75%
rename from device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc
rename to device/bluetooth/bluetooth_adapter_profile_bluez_unittest.cc
index be999019..f64359d 100644
--- a/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_profile_bluez_unittest.cc
@@ -5,9 +5,9 @@
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "device/bluetooth/bluetooth_adapter.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
-#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_profile_bluez.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 #include "device/bluetooth/dbus/bluetooth_profile_service_provider.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
@@ -20,11 +20,11 @@
 using device::BluetoothAdapter;
 using device::BluetoothUUID;
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothAdapterProfileChromeOSTest : public testing::Test {
+class BluetoothAdapterProfileBlueZTest : public testing::Test {
  public:
-  BluetoothAdapterProfileChromeOSTest()
+  BluetoothAdapterProfileBlueZTest()
       : success_callback_count_(0),
         error_callback_count_(0),
         fake_delegate_paired_(
@@ -53,7 +53,7 @@
 
     // Grab a pointer to the adapter.
     device::BluetoothAdapterFactory::GetAdapter(
-        base::Bind(&BluetoothAdapterProfileChromeOSTest::AdapterCallback,
+        base::Bind(&BluetoothAdapterProfileBlueZTest::AdapterCallback,
                    base::Unretained(this)));
     ASSERT_TRUE(adapter_.get() != nullptr);
     ASSERT_TRUE(adapter_->IsInitialized());
@@ -115,17 +115,17 @@
   };
 
   void ProfileSuccessCallback(
-      scoped_ptr<BluetoothAdapterProfileChromeOS> profile) {
+      scoped_ptr<BluetoothAdapterProfileBlueZ> profile) {
     profile_.swap(profile);
     ++success_callback_count_;
   }
 
-  void ProfileUserSuccessCallback(BluetoothAdapterProfileChromeOS* profile) {
+  void ProfileUserSuccessCallback(BluetoothAdapterProfileBlueZ* profile) {
     profile_user_ptr_ = profile;
     ++success_callback_count_;
   }
 
-  void MatchedProfileCallback(BluetoothAdapterProfileChromeOS* profile) {
+  void MatchedProfileCallback(BluetoothAdapterProfileBlueZ* profile) {
     ASSERT_EQ(profile_user_ptr_, profile);
     ++success_callback_count_;
   }
@@ -153,24 +153,24 @@
   FakeDelegate fake_delegate_autopair_;
   FakeDelegate fake_delegate_listen_;
 
-  scoped_ptr<BluetoothAdapterProfileChromeOS> profile_;
+  scoped_ptr<BluetoothAdapterProfileBlueZ> profile_;
 
   // unowned pointer as expected to be used by clients of
-  // BluetoothAdapterChromeOS::UseProfile like BluetoothSocketChromeOS
-  BluetoothAdapterProfileChromeOS* profile_user_ptr_;
+  // BluetoothAdapterBlueZ::UseProfile like BluetoothSocketBlueZ
+  BluetoothAdapterProfileBlueZ* profile_user_ptr_;
 };
 
-TEST_F(BluetoothAdapterProfileChromeOSTest, DelegateCount) {
+TEST_F(BluetoothAdapterProfileBlueZTest, DelegateCount) {
   BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
   bluez::BluetoothProfileManagerClient::Options options;
 
   options.require_authentication.reset(new bool(false));
 
-  BluetoothAdapterProfileChromeOS::Register(
+  BluetoothAdapterProfileBlueZ::Register(
       uuid, options,
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::ProfileSuccessCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::ProfileSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -197,17 +197,17 @@
   EXPECT_EQ(0U, profile_->DelegateCount());
 }
 
-TEST_F(BluetoothAdapterProfileChromeOSTest, BlackHole) {
+TEST_F(BluetoothAdapterProfileBlueZTest, BlackHole) {
   BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
   bluez::BluetoothProfileManagerClient::Options options;
 
   options.require_authentication.reset(new bool(false));
 
-  BluetoothAdapterProfileChromeOS::Register(
+  BluetoothAdapterProfileBlueZ::Register(
       uuid, options,
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::ProfileSuccessCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::ProfileSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -219,10 +219,9 @@
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath),
       bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
-      base::Bind(
-          &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
-          base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusConnectSuccessCallback,
+                 base::Unretained(this)),
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -233,17 +232,17 @@
   EXPECT_EQ(0U, fake_delegate_paired_.connections_);
 }
 
-TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) {
+TEST_F(BluetoothAdapterProfileBlueZTest, Routing) {
   BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
   bluez::BluetoothProfileManagerClient::Options options;
 
   options.require_authentication.reset(new bool(false));
 
-  BluetoothAdapterProfileChromeOS::Register(
+  BluetoothAdapterProfileBlueZ::Register(
       uuid, options,
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::ProfileSuccessCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::ProfileSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -262,10 +261,9 @@
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath),
       bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
-      base::Bind(
-          &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
-          base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusConnectSuccessCallback,
+                 base::Unretained(this)),
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -278,10 +276,9 @@
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLegacyAutopairPath),
       bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
-      base::Bind(
-          &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
-          base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusConnectSuccessCallback,
+                 base::Unretained(this)),
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -295,10 +292,9 @@
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kDisplayPinCodePath),
       bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
-      base::Bind(
-          &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
-          base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusConnectSuccessCallback,
+                 base::Unretained(this)),
+      base::Bind(&BluetoothAdapterProfileBlueZTest::DBusErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -309,11 +305,11 @@
   EXPECT_EQ(1U, fake_delegate_listen_.connections_);
 }
 
-TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegister) {
+TEST_F(BluetoothAdapterProfileBlueZTest, SimultaneousRegister) {
   BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
   bluez::BluetoothProfileManagerClient::Options options;
-  BluetoothAdapterChromeOS* adapter =
-      static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
+  BluetoothAdapterBlueZ* adapter =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
 
   options.require_authentication.reset(new bool(false));
 
@@ -322,18 +318,17 @@
 
   adapter->UseProfile(
       uuid, fake_delegate_paired_.device_path_, options, &fake_delegate_paired_,
-      base::Bind(
-          &BluetoothAdapterProfileChromeOSTest::ProfileUserSuccessCallback,
-          base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::BasicErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::ProfileUserSuccessCallback,
+                 base::Unretained(this)),
+      base::Bind(&BluetoothAdapterProfileBlueZTest::BasicErrorCallback,
                  base::Unretained(this)));
 
   adapter->UseProfile(
       uuid, fake_delegate_autopair_.device_path_, options,
       &fake_delegate_autopair_,
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::MatchedProfileCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::MatchedProfileCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::BasicErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::BasicErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -350,12 +345,12 @@
   message_loop_.RunUntilIdle();
 }
 
-TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegisterFail) {
+TEST_F(BluetoothAdapterProfileBlueZTest, SimultaneousRegisterFail) {
   BluetoothUUID uuid(
       bluez::FakeBluetoothProfileManagerClient::kUnregisterableUuid);
   bluez::BluetoothProfileManagerClient::Options options;
-  BluetoothAdapterChromeOS* adapter =
-      static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
+  BluetoothAdapterBlueZ* adapter =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
 
   options.require_authentication.reset(new bool(false));
 
@@ -364,18 +359,17 @@
 
   adapter->UseProfile(
       uuid, fake_delegate_paired_.device_path_, options, &fake_delegate_paired_,
-      base::Bind(
-          &BluetoothAdapterProfileChromeOSTest::ProfileUserSuccessCallback,
-          base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::BasicErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::ProfileUserSuccessCallback,
+                 base::Unretained(this)),
+      base::Bind(&BluetoothAdapterProfileBlueZTest::BasicErrorCallback,
                  base::Unretained(this)));
 
   adapter->UseProfile(
       uuid, fake_delegate_autopair_.device_path_, options,
       &fake_delegate_autopair_,
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::MatchedProfileCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::MatchedProfileCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothAdapterProfileChromeOSTest::BasicErrorCallback,
+      base::Bind(&BluetoothAdapterProfileBlueZTest::BasicErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -385,4 +379,4 @@
   EXPECT_EQ(2U, error_callback_count_);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos.cc b/device/bluetooth/bluetooth_advertisement_bluez.cc
similarity index 88%
rename from device/bluetooth/bluetooth_advertisement_chromeos.cc
rename to device/bluetooth/bluetooth_advertisement_bluez.cc
index 671977dc..97b78da 100644
--- a/device/bluetooth/bluetooth_advertisement_chromeos.cc
+++ b/device/bluetooth/bluetooth_advertisement_bluez.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_advertisement_chromeos.h"
+#include "device/bluetooth/bluetooth_advertisement_bluez.h"
 
 #include <string>
 
@@ -14,7 +14,7 @@
 #include "base/strings/string_util.h"
 #include "dbus/bus.h"
 #include "dbus/object_path.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
@@ -23,7 +23,7 @@
 
 void UnregisterFailure(device::BluetoothAdvertisement::ErrorCode error) {
   LOG(ERROR)
-      << "BluetoothAdvertisementChromeOS::Unregister failed with error code = "
+      << "BluetoothAdvertisementBlueZ::Unregister failed with error code = "
       << error;
 }
 
@@ -68,11 +68,11 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
-BluetoothAdvertisementChromeOS::BluetoothAdvertisementChromeOS(
+BluetoothAdvertisementBlueZ::BluetoothAdvertisementBlueZ(
     scoped_ptr<device::BluetoothAdvertisement::Data> data,
-    scoped_refptr<BluetoothAdapterChromeOS> adapter)
+    scoped_refptr<BluetoothAdapterBlueZ> adapter)
     : adapter_(adapter) {
   // Generate a new object path - make sure that we strip any -'s from the
   // generated GUID string since object paths can only contain alphanumeric
@@ -93,7 +93,7 @@
       data->solicit_uuids().Pass(), data->service_data().Pass());
 }
 
-void BluetoothAdvertisementChromeOS::Register(
+void BluetoothAdvertisementBlueZ::Register(
     const base::Closure& success_callback,
     const device::BluetoothAdapter::CreateAdvertisementErrorCallback&
         error_callback) {
@@ -105,11 +105,11 @@
           base::Bind(&RegisterErrorCallbackConnector, error_callback));
 }
 
-BluetoothAdvertisementChromeOS::~BluetoothAdvertisementChromeOS() {
+BluetoothAdvertisementBlueZ::~BluetoothAdvertisementBlueZ() {
   Unregister(base::Bind(&base::DoNothing), base::Bind(&UnregisterFailure));
 }
 
-void BluetoothAdvertisementChromeOS::Unregister(
+void BluetoothAdvertisementBlueZ::Unregister(
     const SuccessCallback& success_callback,
     const ErrorCallback& error_callback) {
   // If we don't have a provider, that means we have already been unregistered,
@@ -129,11 +129,11 @@
   provider_.reset();
 }
 
-void BluetoothAdvertisementChromeOS::Released() {
+void BluetoothAdvertisementBlueZ::Released() {
   LOG(WARNING) << "Advertisement released.";
   provider_.reset();
   FOR_EACH_OBSERVER(BluetoothAdvertisement::Observer, observers_,
                     AdvertisementReleased(this));
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos.h b/device/bluetooth/bluetooth_advertisement_bluez.h
similarity index 69%
rename from device/bluetooth/bluetooth_advertisement_chromeos.h
rename to device/bluetooth/bluetooth_advertisement_bluez.h
index 44abec27..bde8cc8 100644
--- a/device/bluetooth/bluetooth_advertisement_chromeos.h
+++ b/device/bluetooth/bluetooth_advertisement_bluez.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_BLUEZ_H_
 
 #include "base/macros.h"
 #include "device/bluetooth/bluetooth_adapter.h"
@@ -15,19 +15,19 @@
 class BluetoothLEAdvertisementServiceProvider;
 }
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothAdapterChromeOS;
+class BluetoothAdapterBlueZ;
 
-// The BluetoothAdvertisementChromeOS class implements BluetoothAdvertisement
+// The BluetoothAdvertisementBlueZ class implements BluetoothAdvertisement
 // for the Chrome OS platform.
-class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisementChromeOS
+class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisementBlueZ
     : public device::BluetoothAdvertisement,
       public bluez::BluetoothLEAdvertisementServiceProvider::Delegate {
  public:
-  BluetoothAdvertisementChromeOS(
+  BluetoothAdvertisementBlueZ(
       scoped_ptr<device::BluetoothAdvertisement::Data> data,
-      scoped_refptr<BluetoothAdapterChromeOS> adapter);
+      scoped_refptr<BluetoothAdapterBlueZ> adapter);
 
   // BluetoothAdvertisement overrides:
   void Unregister(const SuccessCallback& success_callback,
@@ -48,15 +48,15 @@
   }
 
  private:
-  ~BluetoothAdvertisementChromeOS() override;
+  ~BluetoothAdvertisementBlueZ() override;
 
   // Adapter this advertisement is advertising on.
-  scoped_refptr<BluetoothAdapterChromeOS> adapter_;
+  scoped_refptr<BluetoothAdapterBlueZ> adapter_;
   scoped_ptr<bluez::BluetoothLEAdvertisementServiceProvider> provider_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc b/device/bluetooth/bluetooth_advertisement_bluez_unittest.cc
similarity index 86%
rename from device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc
rename to device/bluetooth/bluetooth_advertisement_bluez_unittest.cc
index 165dc8d9..6ef7a63 100644
--- a/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_advertisement_bluez_unittest.cc
@@ -12,7 +12,7 @@
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_advertisement.h"
-#include "device/bluetooth/bluetooth_advertisement_chromeos.h"
+#include "device/bluetooth/bluetooth_advertisement_bluez.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -21,7 +21,7 @@
 using device::BluetoothAdapterFactory;
 using device::BluetoothAdvertisement;
 
-namespace chromeos {
+namespace bluez {
 
 class TestAdvertisementObserver : public BluetoothAdvertisement::Observer {
  public:
@@ -49,7 +49,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestAdvertisementObserver);
 };
 
-class BluetoothAdvertisementChromeOSTest : public testing::Test {
+class BluetoothAdvertisementBlueZTest : public testing::Test {
  public:
   void SetUp() override {
     bluez::BluezDBusManager::Initialize(NULL, true);
@@ -76,7 +76,7 @@
   // Gets the existing Bluetooth adapter.
   void GetAdapter() {
     BluetoothAdapterFactory::GetAdapter(
-        base::Bind(&BluetoothAdvertisementChromeOSTest::GetAdapterCallback,
+        base::Bind(&BluetoothAdvertisementBlueZTest::GetAdapterCallback,
                    base::Unretained(this)));
   }
 
@@ -109,11 +109,10 @@
 
     adapter_->RegisterAdvertisement(
         CreateAdvertisementData().Pass(),
-        base::Bind(&BluetoothAdvertisementChromeOSTest::RegisterCallback,
+        base::Bind(&BluetoothAdvertisementBlueZTest::RegisterCallback,
                    base::Unretained(this)),
-        base::Bind(
-            &BluetoothAdvertisementChromeOSTest::AdvertisementErrorCallback,
-            base::Unretained(this)));
+        base::Bind(&BluetoothAdvertisementBlueZTest::AdvertisementErrorCallback,
+                   base::Unretained(this)));
 
     message_loop_.RunUntilIdle();
     return advertisement_;
@@ -122,18 +121,17 @@
   void UnregisterAdvertisement(
       scoped_refptr<BluetoothAdvertisement> advertisement) {
     advertisement->Unregister(
-        base::Bind(&BluetoothAdvertisementChromeOSTest::Callback,
+        base::Bind(&BluetoothAdvertisementBlueZTest::Callback,
                    base::Unretained(this)),
-        base::Bind(
-            &BluetoothAdvertisementChromeOSTest::AdvertisementErrorCallback,
-            base::Unretained(this)));
+        base::Bind(&BluetoothAdvertisementBlueZTest::AdvertisementErrorCallback,
+                   base::Unretained(this)));
 
     message_loop_.RunUntilIdle();
   }
 
   void TriggerReleased(scoped_refptr<BluetoothAdvertisement> advertisement) {
-    BluetoothAdvertisementChromeOS* adv =
-        static_cast<BluetoothAdvertisementChromeOS*>(advertisement.get());
+    BluetoothAdvertisementBlueZ* adv =
+        static_cast<BluetoothAdvertisementBlueZ*>(advertisement.get());
     bluez::FakeBluetoothLEAdvertisementServiceProvider* provider =
         static_cast<bluez::FakeBluetoothLEAdvertisementServiceProvider*>(
             adv->provider());
@@ -190,7 +188,7 @@
   scoped_refptr<BluetoothAdvertisement> advertisement_;
 };
 
-TEST_F(BluetoothAdvertisementChromeOSTest, RegisterSucceeded) {
+TEST_F(BluetoothAdvertisementBlueZTest, RegisterSucceeded) {
   scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement();
   ExpectSuccess();
   EXPECT_NE(nullptr, advertisement);
@@ -199,7 +197,7 @@
   ExpectSuccess();
 }
 
-TEST_F(BluetoothAdvertisementChromeOSTest, DoubleRegisterFailed) {
+TEST_F(BluetoothAdvertisementBlueZTest, DoubleRegisterFailed) {
   scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement();
   ExpectSuccess();
   EXPECT_NE(nullptr, advertisement);
@@ -210,7 +208,7 @@
   EXPECT_EQ(nullptr, advertisement2);
 }
 
-TEST_F(BluetoothAdvertisementChromeOSTest, DoubleUnregisterFailed) {
+TEST_F(BluetoothAdvertisementBlueZTest, DoubleUnregisterFailed) {
   scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement();
   ExpectSuccess();
   EXPECT_NE(nullptr, advertisement);
@@ -224,7 +222,7 @@
   ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
 }
 
-TEST_F(BluetoothAdvertisementChromeOSTest, UnregisterAfterReleasedFailed) {
+TEST_F(BluetoothAdvertisementBlueZTest, UnregisterAfterReleasedFailed) {
   scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement();
   ExpectSuccess();
   EXPECT_NE(nullptr, advertisement);
@@ -239,4 +237,4 @@
   ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.cc b/device/bluetooth/bluetooth_audio_sink_bluez.cc
similarity index 81%
rename from device/bluetooth/bluetooth_audio_sink_chromeos.cc
rename to device/bluetooth/bluetooth_audio_sink_bluez.cc
index 9bb4b60..fca894b 100644
--- a/device/bluetooth/bluetooth_audio_sink_chromeos.cc
+++ b/device/bluetooth/bluetooth_audio_sink_bluez.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_audio_sink_chromeos.h"
+#include "device/bluetooth/bluetooth_audio_sink_bluez.h"
 
 #include <unistd.h>
 
@@ -15,7 +15,7 @@
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "dbus/message.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
 using dbus::ObjectPath;
@@ -71,17 +71,16 @@
 }
 
 // A dummy error callback for calling Unregister() in destructor.
-void UnregisterErrorCallback(
-    device::BluetoothAudioSink::ErrorCode error_code) {
+void UnregisterErrorCallback(device::BluetoothAudioSink::ErrorCode error_code) {
   VLOG(1) << "UnregisterErrorCallback - " << ErrorCodeToString(error_code)
           << "(" << error_code << ")";
 }
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
-BluetoothAudioSinkChromeOS::BluetoothAudioSinkChromeOS(
+BluetoothAudioSinkBlueZ::BluetoothAudioSinkBlueZ(
     scoped_refptr<device::BluetoothAdapter> adapter)
     : state_(BluetoothAudioSink::STATE_INVALID),
       volume_(BluetoothAudioSink::kInvalidVolume),
@@ -90,7 +89,7 @@
       read_has_failed_(false),
       adapter_(adapter),
       weak_ptr_factory_(this) {
-  VLOG(1) << "BluetoothAudioSinkChromeOS created";
+  VLOG(1) << "BluetoothAudioSinkBlueZ created";
 
   CHECK(adapter_.get());
   CHECK(adapter_->IsPresent());
@@ -111,8 +110,8 @@
   StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED);
 }
 
-BluetoothAudioSinkChromeOS::~BluetoothAudioSinkChromeOS() {
-  VLOG(1) << "BluetoothAudioSinkChromeOS destroyed";
+BluetoothAudioSinkBlueZ::~BluetoothAudioSinkBlueZ() {
+  VLOG(1) << "BluetoothAudioSinkBlueZ destroyed";
 
   DCHECK(adapter_.get());
 
@@ -134,7 +133,7 @@
   transport->RemoveObserver(this);
 }
 
-void BluetoothAudioSinkChromeOS::Unregister(
+void BluetoothAudioSinkBlueZ::Unregister(
     const base::Closure& callback,
     const device::BluetoothAudioSink::ErrorCallback& error_callback) {
   VLOG(1) << "Unregister";
@@ -147,35 +146,34 @@
   CHECK(media);
 
   media->UnregisterEndpoint(
-      media_path_,
-      endpoint_path_,
-      base::Bind(&BluetoothAudioSinkChromeOS::OnUnregisterSucceeded,
+      media_path_, endpoint_path_,
+      base::Bind(&BluetoothAudioSinkBlueZ::OnUnregisterSucceeded,
                  weak_ptr_factory_.GetWeakPtr(), callback),
-      base::Bind(&BluetoothAudioSinkChromeOS::OnUnregisterFailed,
+      base::Bind(&BluetoothAudioSinkBlueZ::OnUnregisterFailed,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothAudioSinkChromeOS::AddObserver(
+void BluetoothAudioSinkBlueZ::AddObserver(
     BluetoothAudioSink::Observer* observer) {
   CHECK(observer);
   observers_.AddObserver(observer);
 }
 
-void BluetoothAudioSinkChromeOS::RemoveObserver(
+void BluetoothAudioSinkBlueZ::RemoveObserver(
     BluetoothAudioSink::Observer* observer) {
   CHECK(observer);
   observers_.RemoveObserver(observer);
 }
 
-BluetoothAudioSink::State BluetoothAudioSinkChromeOS::GetState() const {
+BluetoothAudioSink::State BluetoothAudioSinkBlueZ::GetState() const {
   return state_;
 }
 
-uint16_t BluetoothAudioSinkChromeOS::GetVolume() const {
+uint16_t BluetoothAudioSinkBlueZ::GetVolume() const {
   return volume_;
 }
 
-void BluetoothAudioSinkChromeOS::Register(
+void BluetoothAudioSinkBlueZ::Register(
     const BluetoothAudioSink::Options& options,
     const base::Closure& callback,
     const BluetoothAudioSink::ErrorCallback& error_callback) {
@@ -202,29 +200,28 @@
   endpoint_properties.codec = options_.codec;
   endpoint_properties.capabilities = options_.capabilities;
 
-  media_path_ = static_cast<BluetoothAdapterChromeOS*>(
-      adapter_.get())->object_path();
+  media_path_ =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get())->object_path();
 
   bluez::BluetoothMediaClient* media =
       bluez::BluezDBusManager::Get()->GetBluetoothMediaClient();
   CHECK(media);
   media->RegisterEndpoint(
-      media_path_,
-      endpoint_path_,
-      endpoint_properties,
-      base::Bind(&BluetoothAudioSinkChromeOS::OnRegisterSucceeded,
+      media_path_, endpoint_path_, endpoint_properties,
+      base::Bind(&BluetoothAudioSinkBlueZ::OnRegisterSucceeded,
                  weak_ptr_factory_.GetWeakPtr(), callback),
-      base::Bind(&BluetoothAudioSinkChromeOS::OnRegisterFailed,
+      base::Bind(&BluetoothAudioSinkBlueZ::OnRegisterFailed,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
 bluez::BluetoothMediaEndpointServiceProvider*
-BluetoothAudioSinkChromeOS::GetEndpointServiceProvider() {
+BluetoothAudioSinkBlueZ::GetEndpointServiceProvider() {
   return media_endpoint_.get();
 }
 
-void BluetoothAudioSinkChromeOS::AdapterPresentChanged(
-    device::BluetoothAdapter* adapter, bool present) {
+void BluetoothAudioSinkBlueZ::AdapterPresentChanged(
+    device::BluetoothAdapter* adapter,
+    bool present) {
   VLOG(1) << "AdapterPresentChanged: " << present;
 
   if (adapter != adapter_.get())
@@ -238,8 +235,9 @@
   }
 }
 
-void BluetoothAudioSinkChromeOS::AdapterPoweredChanged(
-    device::BluetoothAdapter* adapter, bool powered) {
+void BluetoothAudioSinkBlueZ::AdapterPoweredChanged(
+    device::BluetoothAdapter* adapter,
+    bool powered) {
   VLOG(1) << "AdapterPoweredChanged: " << powered;
 
   if (adapter != adapter_.get())
@@ -253,14 +251,14 @@
     StateChanged(BluetoothAudioSink::STATE_DISCONNECTED);
 }
 
-void BluetoothAudioSinkChromeOS::MediaRemoved(const ObjectPath& object_path) {
+void BluetoothAudioSinkBlueZ::MediaRemoved(const ObjectPath& object_path) {
   if (object_path == media_path_) {
     VLOG(1) << "MediaRemoved: " << object_path.value();
     StateChanged(BluetoothAudioSink::STATE_INVALID);
   }
 }
 
-void BluetoothAudioSinkChromeOS::MediaTransportRemoved(
+void BluetoothAudioSinkBlueZ::MediaTransportRemoved(
     const ObjectPath& object_path) {
   // Whenever powered of |adapter_| turns false while present stays true, media
   // transport object should be removed accordingly, and the state should be
@@ -271,7 +269,7 @@
   }
 }
 
-void BluetoothAudioSinkChromeOS::MediaTransportPropertyChanged(
+void BluetoothAudioSinkBlueZ::MediaTransportPropertyChanged(
     const ObjectPath& object_path,
     const std::string& property_name) {
   if (object_path != transport_path_)
@@ -302,7 +300,7 @@
   }
 }
 
-void BluetoothAudioSinkChromeOS::SetConfiguration(
+void BluetoothAudioSinkBlueZ::SetConfiguration(
     const ObjectPath& transport_path,
     const TransportProperties& properties) {
   VLOG(1) << "SetConfiguration";
@@ -322,14 +320,14 @@
   StateChanged(BluetoothAudioSink::STATE_IDLE);
 }
 
-void BluetoothAudioSinkChromeOS::SelectConfiguration(
+void BluetoothAudioSinkBlueZ::SelectConfiguration(
     const std::vector<uint8_t>& capabilities,
     const SelectConfigurationCallback& callback) {
   VLOG(1) << "SelectConfiguration";
   callback.Run(options_.capabilities);
 }
 
-void BluetoothAudioSinkChromeOS::ClearConfiguration(
+void BluetoothAudioSinkBlueZ::ClearConfiguration(
     const ObjectPath& transport_path) {
   if (transport_path != transport_path_)
     return;
@@ -338,33 +336,32 @@
   StateChanged(BluetoothAudioSink::STATE_DISCONNECTED);
 }
 
-void BluetoothAudioSinkChromeOS::Released() {
+void BluetoothAudioSinkBlueZ::Released() {
   VLOG(1) << "Released";
   StateChanged(BluetoothAudioSink::STATE_INVALID);
 }
 
-void BluetoothAudioSinkChromeOS::OnFileCanReadWithoutBlocking(int fd) {
+void BluetoothAudioSinkBlueZ::OnFileCanReadWithoutBlocking(int fd) {
   ReadFromFile();
 }
 
-void BluetoothAudioSinkChromeOS::OnFileCanWriteWithoutBlocking(int fd) {
+void BluetoothAudioSinkBlueZ::OnFileCanWriteWithoutBlocking(int fd) {
   // Do nothing for now.
 }
 
-void BluetoothAudioSinkChromeOS::AcquireFD() {
+void BluetoothAudioSinkBlueZ::AcquireFD() {
   VLOG(1) << "AcquireFD - transport path: " << transport_path_.value();
 
   read_has_failed_ = false;
 
   bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient()->Acquire(
-      transport_path_,
-      base::Bind(&BluetoothAudioSinkChromeOS::OnAcquireSucceeded,
-                 weak_ptr_factory_.GetWeakPtr()),
-      base::Bind(&BluetoothAudioSinkChromeOS::OnAcquireFailed,
+      transport_path_, base::Bind(&BluetoothAudioSinkBlueZ::OnAcquireSucceeded,
+                                  weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothAudioSinkBlueZ::OnAcquireFailed,
                  weak_ptr_factory_.GetWeakPtr()));
 }
 
-void BluetoothAudioSinkChromeOS::WatchFD() {
+void BluetoothAudioSinkBlueZ::WatchFD() {
   CHECK(file_.get() && file_->IsValid());
 
   VLOG(1) << "WatchFD - file: " << file_->GetPlatformFile()
@@ -375,7 +372,7 @@
       &fd_read_watcher_, this);
 }
 
-void BluetoothAudioSinkChromeOS::StopWatchingFD() {
+void BluetoothAudioSinkBlueZ::StopWatchingFD() {
   if (!file_.get()) {
     VLOG(1) << "StopWatchingFD - skip";
     return;
@@ -390,7 +387,7 @@
   file_.reset();  // This will close the file descriptor.
 }
 
-void BluetoothAudioSinkChromeOS::ReadFromFile() {
+void BluetoothAudioSinkBlueZ::ReadFromFile() {
   DCHECK(file_.get() && file_->IsValid());
   DCHECK(data_.get());
 
@@ -411,8 +408,7 @@
       BluetoothAudioSinkDataAvailable(this, data_.get(), size, read_mtu_));
 }
 
-void BluetoothAudioSinkChromeOS::StateChanged(
-    BluetoothAudioSink::State state) {
+void BluetoothAudioSinkBlueZ::StateChanged(BluetoothAudioSink::State state) {
   if (state == state_)
     return;
 
@@ -443,7 +439,7 @@
                     BluetoothAudioSinkStateChanged(this, state_));
 }
 
-void BluetoothAudioSinkChromeOS::VolumeChanged(uint16_t volume) {
+void BluetoothAudioSinkBlueZ::VolumeChanged(uint16_t volume) {
   if (volume == volume_)
     return;
 
@@ -454,7 +450,7 @@
                     BluetoothAudioSinkVolumeChanged(this, volume_));
 }
 
-void BluetoothAudioSinkChromeOS::OnRegisterSucceeded(
+void BluetoothAudioSinkBlueZ::OnRegisterSucceeded(
     const base::Closure& callback) {
   DCHECK(media_endpoint_.get());
   VLOG(1) << "OnRegisterSucceeded";
@@ -463,7 +459,7 @@
   callback.Run();
 }
 
-void BluetoothAudioSinkChromeOS::OnRegisterFailed(
+void BluetoothAudioSinkBlueZ::OnRegisterFailed(
     const BluetoothAudioSink::ErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -474,7 +470,7 @@
   error_callback.Run(BluetoothAudioSink::ERROR_NOT_REGISTERED);
 }
 
-void BluetoothAudioSinkChromeOS::OnUnregisterSucceeded(
+void BluetoothAudioSinkBlueZ::OnUnregisterSucceeded(
     const base::Closure& callback) {
   VLOG(1) << "Unregistered - endpoint: " << endpoint_path_.value();
 
@@ -484,7 +480,7 @@
   callback.Run();
 }
 
-void BluetoothAudioSinkChromeOS::OnUnregisterFailed(
+void BluetoothAudioSinkBlueZ::OnUnregisterFailed(
     const device::BluetoothAudioSink::ErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -494,10 +490,9 @@
   error_callback.Run(BluetoothAudioSink::ERROR_NOT_UNREGISTERED);
 }
 
-void BluetoothAudioSinkChromeOS::OnAcquireSucceeded(
-    dbus::FileDescriptor* fd,
-    const uint16_t read_mtu,
-    const uint16_t write_mtu) {
+void BluetoothAudioSinkBlueZ::OnAcquireSucceeded(dbus::FileDescriptor* fd,
+                                                 const uint16_t read_mtu,
+                                                 const uint16_t write_mtu) {
   CHECK(fd);
   fd->CheckValidity();
   CHECK(fd->is_valid() && fd->value() != kInvalidFd);
@@ -526,31 +521,31 @@
           << ", read MTU: " << read_mtu_ << ", write MTU: " << write_mtu_;
 }
 
-void BluetoothAudioSinkChromeOS::OnAcquireFailed(
+void BluetoothAudioSinkBlueZ::OnAcquireFailed(
     const std::string& error_name,
     const std::string& error_message) {
   VLOG(1) << "OnAcquireFailed - error name: " << error_name
           << ", error message: " << error_message;
 }
 
-void BluetoothAudioSinkChromeOS::OnReleaseFDSucceeded() {
+void BluetoothAudioSinkBlueZ::OnReleaseFDSucceeded() {
   VLOG(1) << "OnReleaseFDSucceeded";
 }
 
-void BluetoothAudioSinkChromeOS::OnReleaseFDFailed(
+void BluetoothAudioSinkBlueZ::OnReleaseFDFailed(
     const std::string& error_name,
     const std::string& error_message) {
   VLOG(1) << "OnReleaseFDFailed - error name: " << error_name
           << ", error message: " << error_message;
 }
 
-void BluetoothAudioSinkChromeOS::ResetMedia() {
+void BluetoothAudioSinkBlueZ::ResetMedia() {
   VLOG(1) << "ResetMedia";
 
   media_path_ = dbus::ObjectPath("");
 }
 
-void BluetoothAudioSinkChromeOS::ResetTransport() {
+void BluetoothAudioSinkBlueZ::ResetTransport() {
   if (!transport_path_.IsValid()) {
     VLOG(1) << "ResetTransport - skip";
     return;
@@ -565,11 +560,11 @@
   file_.reset();
 }
 
-void BluetoothAudioSinkChromeOS::ResetEndpoint() {
+void BluetoothAudioSinkBlueZ::ResetEndpoint() {
   VLOG(1) << "ResetEndpoint";
 
   endpoint_path_ = ObjectPath("");
   media_endpoint_ = nullptr;
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.h b/device/bluetooth/bluetooth_audio_sink_bluez.h
similarity index 91%
rename from device/bluetooth/bluetooth_audio_sink_chromeos.h
rename to device/bluetooth/bluetooth_audio_sink_bluez.h
index 750b31d..1c43d3a 100644
--- a/device/bluetooth/bluetooth_audio_sink_chromeos.h
+++ b/device/bluetooth/bluetooth_audio_sink_bluez.h
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_BLUEZ_H_
 
 #include <stdint.h>
 #include <string>
 #include <vector>
 
 #include "base/files/file.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_loop.h"
@@ -23,11 +24,11 @@
 #include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h"
 #include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothAudioSinkChromeOSTest;
+class BluetoothAudioSinkBlueZTest;
 
-class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkChromeOS
+class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkBlueZ
     : public device::BluetoothAudioSink,
       public device::BluetoothAdapter::Observer,
       public bluez::BluetoothMediaClient::Observer,
@@ -35,7 +36,7 @@
       public bluez::BluetoothMediaEndpointServiceProvider::Delegate,
       public base::MessageLoopForIO::Watcher {
  public:
-  explicit BluetoothAudioSinkChromeOS(
+  explicit BluetoothAudioSinkBlueZ(
       scoped_refptr<device::BluetoothAdapter> adapter);
 
   // device::BluetoothAudioSink overrides.
@@ -53,7 +54,7 @@
   // Registers a BluetoothAudioSink. User applications can use |options| to
   // configure the audio sink. |callback| will be executed if the audio sink is
   // successfully registered, otherwise |error_callback| will be called. Called
-  // by BluetoothAdapterChromeOS.
+  // by BluetoothAdapterBlueZ.
   void Register(
       const device::BluetoothAudioSink::Options& options,
       const base::Closure& callback,
@@ -64,7 +65,7 @@
   bluez::BluetoothMediaEndpointServiceProvider* GetEndpointServiceProvider();
 
  private:
-  ~BluetoothAudioSinkChromeOS() override;
+  ~BluetoothAudioSinkBlueZ() override;
 
   // device::BluetoothAdapter::Observer overrides.
   void AdapterPresentChanged(device::BluetoothAdapter* adapter,
@@ -157,7 +158,7 @@
   void ResetTransport();
   void ResetEndpoint();
 
-  // The connection state between the BluetoothAudioSinkChromeOS and the remote
+  // The connection state between the BluetoothAudioSinkBlueZ and the remote
   // device.
   device::BluetoothAudioSink::State state_;
 
@@ -196,7 +197,7 @@
   dbus::ObjectPath endpoint_path_;
 
   // BT adapter which the audio sink binds to. |adapter_| should outlive
-  // a BluetoothAudioSinkChromeOS object.
+  // a BluetoothAudioSinkBlueZ object.
   scoped_refptr<device::BluetoothAdapter> adapter_;
 
   // Options used to initiate Media Endpoint and select configuration for the
@@ -207,16 +208,16 @@
   scoped_ptr<bluez::BluetoothMediaEndpointServiceProvider> media_endpoint_;
 
   // List of observers interested in event notifications from us. Objects in
-  // |observers_| are expected to outlive a BluetoothAudioSinkChromeOS object.
+  // |observers_| are expected to outlive a BluetoothAudioSinkBlueZ object.
   base::ObserverList<BluetoothAudioSink::Observer> observers_;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothAudioSinkChromeOS> weak_ptr_factory_;
+  base::WeakPtrFactory<BluetoothAudioSinkBlueZ> weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAudioSinkChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothAudioSinkBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc b/device/bluetooth/bluetooth_audio_sink_bluez_unittest.cc
similarity index 85%
rename from device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc
rename to device/bluetooth/bluetooth_audio_sink_bluez_unittest.cc
index 5f51cb8a0..bf2e063 100644
--- a/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_audio_sink_bluez_unittest.cc
@@ -12,7 +12,7 @@
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_audio_sink.h"
-#include "device/bluetooth/bluetooth_audio_sink_chromeos.h"
+#include "device/bluetooth/bluetooth_audio_sink_bluez.h"
 #include "device/bluetooth/dbus/bluetooth_media_client.h"
 #include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h"
 #include "device/bluetooth/dbus/bluetooth_media_transport_client.h"
@@ -28,7 +28,7 @@
 using device::BluetoothAdapterFactory;
 using device::BluetoothAudioSink;
 
-namespace chromeos {
+namespace bluez {
 
 class TestAudioSinkObserver : public BluetoothAudioSink::Observer {
  public:
@@ -79,7 +79,7 @@
   scoped_refptr<BluetoothAudioSink> audio_sink_;
 };
 
-class BluetoothAudioSinkChromeOSTest : public testing::Test {
+class BluetoothAudioSinkBlueZTest : public testing::Test {
  public:
   void SetUp() override {
     bluez::BluezDBusManager::Initialize(NULL, true);
@@ -126,7 +126,7 @@
   // Gets the existing Bluetooth adapter.
   void GetAdapter() {
     BluetoothAdapterFactory::GetAdapter(
-        base::Bind(&BluetoothAudioSinkChromeOSTest::GetAdapterCallback,
+        base::Bind(&BluetoothAudioSinkBlueZTest::GetAdapterCallback,
                    base::Unretained(this)));
   }
 
@@ -136,12 +136,11 @@
 
     ASSERT_NE(adapter_.get(), nullptr);
     ASSERT_TRUE(adapter_->IsInitialized());
-    adapter_->SetPowered(
-        true,
-        base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
-                   base::Unretained(this)),
-        base::Bind(&BluetoothAudioSinkChromeOSTest::ErrorCallback,
-                   base::Unretained(this)));
+    adapter_->SetPowered(true,
+                         base::Bind(&BluetoothAudioSinkBlueZTest::Callback,
+                                    base::Unretained(this)),
+                         base::Bind(&BluetoothAudioSinkBlueZTest::ErrorCallback,
+                                    base::Unretained(this)));
     ASSERT_TRUE(adapter_->IsPresent());
     ASSERT_TRUE(adapter_->IsPowered());
     EXPECT_EQ(callback_count_, 1);
@@ -151,7 +150,7 @@
     --callback_count_;
   }
 
-  // Registers BluetoothAudioSinkChromeOS with default codec and capabilities.
+  // Registers BluetoothAudioSinkBlueZ with default codec and capabilities.
   // If the audio sink is retrieved successfully, the state changes to
   // STATE_DISCONNECTED.
   void GetAudioSink() {
@@ -163,10 +162,9 @@
 
     // Registers |audio_sink_| with valid codec and capabilities
     adapter_->RegisterAudioSink(
-        options,
-        base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
-                   base::Unretained(this)),
-        base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
+        options, base::Bind(&BluetoothAudioSinkBlueZTest::RegisterCallback,
+                            base::Unretained(this)),
+        base::Bind(&BluetoothAudioSinkBlueZTest::RegisterErrorCallback,
                    base::Unretained(this)));
 
     observer_.reset(new TestAudioSinkObserver(audio_sink_));
@@ -177,18 +175,17 @@
   }
 
   void GetFakeMediaEndpoint() {
-    BluetoothAudioSinkChromeOS* audio_sink_chromeos =
-        static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get());
-    ASSERT_NE(audio_sink_chromeos, nullptr);
+    BluetoothAudioSinkBlueZ* audio_sink_bluez =
+        static_cast<BluetoothAudioSinkBlueZ*>(audio_sink_.get());
+    ASSERT_NE(audio_sink_bluez, nullptr);
 
     media_endpoint_ =
         static_cast<bluez::FakeBluetoothMediaEndpointServiceProvider*>(
-            audio_sink_chromeos->GetEndpointServiceProvider());
+            audio_sink_bluez->GetEndpointServiceProvider());
   }
 
   // Called whenever RegisterAudioSink is completed successfully.
-  void RegisterCallback(
-      scoped_refptr<BluetoothAudioSink> audio_sink) {
+  void RegisterCallback(scoped_refptr<BluetoothAudioSink> audio_sink) {
     ++callback_count_;
     audio_sink_ = audio_sink;
 
@@ -221,13 +218,9 @@
   }
 
   // Generic callbacks.
-  void Callback() {
-    ++callback_count_;
-  }
+  void Callback() { ++callback_count_; }
 
-  void ErrorCallback() {
-    ++error_callback_count_;
-  }
+  void ErrorCallback() { ++error_callback_count_; }
 
  protected:
   int callback_count_;
@@ -248,21 +241,20 @@
       properties_;
 };
 
-TEST_F(BluetoothAudioSinkChromeOSTest, RegisterSucceeded) {
+TEST_F(BluetoothAudioSinkBlueZTest, RegisterSucceeded) {
   GetAudioSink();
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, RegisterFailedWithInvalidOptions) {
+TEST_F(BluetoothAudioSinkBlueZTest, RegisterFailedWithInvalidOptions) {
   // Sets options with an invalid codec and valid capabilities.
   BluetoothAudioSink::Options options;
   options.codec = 0xff;
   options.capabilities = std::vector<uint8_t>({0x3f, 0xff, 0x12, 0x35});
 
   adapter_->RegisterAudioSink(
-      options,
-      base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
+      options, base::Bind(&BluetoothAudioSinkBlueZTest::RegisterCallback,
+                          base::Unretained(this)),
+      base::Bind(&BluetoothAudioSinkBlueZTest::RegisterErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(callback_count_, 0);
@@ -272,24 +264,23 @@
   options.codec = 0x00;
   options.capabilities.clear();
   adapter_->RegisterAudioSink(
-      options,
-      base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::RegisterErrorCallback,
+      options, base::Bind(&BluetoothAudioSinkBlueZTest::RegisterCallback,
+                          base::Unretained(this)),
+      base::Bind(&BluetoothAudioSinkBlueZTest::RegisterErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(callback_count_, 0);
   EXPECT_EQ(error_callback_count_, 2);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, SelectConfiguration) {
+TEST_F(BluetoothAudioSinkBlueZTest, SelectConfiguration) {
   GetAudioSink();
 
   // Simulates calling SelectConfiguration on the media endpoint object owned by
   // |audio_sink_| with some fake capabilities.
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -299,12 +290,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 0);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, SetConfiguration) {
+TEST_F(BluetoothAudioSinkBlueZTest, SetConfiguration) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -327,12 +318,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 1);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, SetConfigurationWithUnexpectedState) {
+TEST_F(BluetoothAudioSinkBlueZTest, SetConfigurationWithUnexpectedState) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -358,7 +349,7 @@
 // Checks if the observer is notified on media-removed event when the state of
 // |audio_sink_| is STATE_DISCONNECTED. Once the media object is removed, the
 // audio sink is no longer valid.
-TEST_F(BluetoothAudioSinkChromeOSTest, MediaRemovedDuringDisconnectedState) {
+TEST_F(BluetoothAudioSinkBlueZTest, MediaRemovedDuringDisconnectedState) {
   GetAudioSink();
 
   // Gets the media object and makes it invisible to see if the state of the
@@ -376,12 +367,12 @@
 // Checks if the observer is  notified on media-removed event when the state of
 // |audio_sink_| is STATE_IDLE. Once the media object is removed, the audio sink
 // is no longer valid.
-TEST_F(BluetoothAudioSinkChromeOSTest, MediaRemovedDuringIdleState) {
+TEST_F(BluetoothAudioSinkBlueZTest, MediaRemovedDuringIdleState) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -416,12 +407,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 2);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, MediaRemovedDuringActiveState) {
+TEST_F(BluetoothAudioSinkBlueZTest, MediaRemovedDuringActiveState) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -469,12 +460,12 @@
 // Checks if the observer is notified on transport-removed event when the state
 // of |audio_sink_| is STATE_IDEL. Once the media transport object is removed,
 // the audio sink is disconnected.
-TEST_F(BluetoothAudioSinkChromeOSTest, TransportRemovedDuringIdleState) {
+TEST_F(BluetoothAudioSinkBlueZTest, TransportRemovedDuringIdleState) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -503,12 +494,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 2);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, TransportRemovedDuringActiveState) {
+TEST_F(BluetoothAudioSinkBlueZTest, TransportRemovedDuringActiveState) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -547,16 +538,14 @@
   EXPECT_EQ(observer_->volume_changed_count_, 2);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest,
+TEST_F(BluetoothAudioSinkBlueZTest,
        AdapterPoweredChangedDuringDisconnectedState) {
   GetAudioSink();
 
-  adapter_->SetPowered(
-      false,
-      base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+  adapter_->SetPowered(false, base::Bind(&BluetoothAudioSinkBlueZTest::Callback,
+                                         base::Unretained(this)),
+                       base::Bind(&BluetoothAudioSinkBlueZTest::ErrorCallback,
+                                  base::Unretained(this)));
 
   EXPECT_TRUE(adapter_->IsPresent());
   EXPECT_FALSE(adapter_->IsPowered());
@@ -566,12 +555,10 @@
   EXPECT_EQ(observer_->state_changed_count_, 0);
   EXPECT_EQ(observer_->volume_changed_count_, 0);
 
-  adapter_->SetPowered(
-      true,
-      base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+  adapter_->SetPowered(true, base::Bind(&BluetoothAudioSinkBlueZTest::Callback,
+                                        base::Unretained(this)),
+                       base::Bind(&BluetoothAudioSinkBlueZTest::ErrorCallback,
+                                  base::Unretained(this)));
 
   EXPECT_TRUE(adapter_->IsPresent());
   EXPECT_TRUE(adapter_->IsPowered());
@@ -582,12 +569,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 0);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, AdapterPoweredChangedDuringIdleState) {
+TEST_F(BluetoothAudioSinkBlueZTest, AdapterPoweredChangedDuringIdleState) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -606,12 +593,10 @@
   EXPECT_EQ(observer_->state_changed_count_, 1);
   EXPECT_EQ(observer_->volume_changed_count_, 1);
 
-  adapter_->SetPowered(
-      false,
-      base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+  adapter_->SetPowered(false, base::Bind(&BluetoothAudioSinkBlueZTest::Callback,
+                                         base::Unretained(this)),
+                       base::Bind(&BluetoothAudioSinkBlueZTest::ErrorCallback,
+                                  base::Unretained(this)));
   GetFakeMediaEndpoint();
 
   EXPECT_TRUE(adapter_->IsPresent());
@@ -624,14 +609,14 @@
   EXPECT_EQ(observer_->volume_changed_count_, 2);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest,
+TEST_F(BluetoothAudioSinkBlueZTest,
        UnregisterAudioSinkDuringDisconnectedState) {
   GetAudioSink();
 
   audio_sink_->Unregister(
-      base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::Callback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::UnregisterErrorCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::UnregisterErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID);
@@ -641,12 +626,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 0);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, UnregisterAudioSinkDuringIdleState) {
+TEST_F(BluetoothAudioSinkBlueZTest, UnregisterAudioSinkDuringIdleState) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -666,9 +651,9 @@
   EXPECT_EQ(observer_->volume_changed_count_, 1);
 
   audio_sink_->Unregister(
-      base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::Callback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::UnregisterErrorCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::UnregisterErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID);
@@ -682,12 +667,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 2);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, UnregisterAudioSinkDuringActiveState) {
+TEST_F(BluetoothAudioSinkBlueZTest, UnregisterAudioSinkDuringActiveState) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -717,9 +702,9 @@
   EXPECT_EQ(observer_->state_changed_count_, 3);
 
   audio_sink_->Unregister(
-      base::Bind(&BluetoothAudioSinkChromeOSTest::Callback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::Callback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::UnregisterErrorCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::UnregisterErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_INVALID);
@@ -729,12 +714,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 2);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, StateChanged) {
+TEST_F(BluetoothAudioSinkBlueZTest, StateChanged) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -761,12 +746,12 @@
   EXPECT_EQ(observer_->volume_changed_count_, 1);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, VolumeChanged) {
+TEST_F(BluetoothAudioSinkBlueZTest, VolumeChanged) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -807,12 +792,12 @@
   EXPECT_EQ(audio_sink_->GetVolume(), BluetoothAudioSink::kInvalidVolume);
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, AcquireFD) {
+TEST_F(BluetoothAudioSinkBlueZTest, AcquireFD) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -850,12 +835,12 @@
 }
 
 // Tests the case where the remote device pauses and resume audio streaming.
-TEST_F(BluetoothAudioSinkChromeOSTest, PauseAndResume) {
+TEST_F(BluetoothAudioSinkBlueZTest, PauseAndResume) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -908,12 +893,12 @@
   EXPECT_EQ(observer_->total_read_, data_two.size());
 }
 
-TEST_F(BluetoothAudioSinkChromeOSTest, ContinuouslyStreaming) {
+TEST_F(BluetoothAudioSinkBlueZTest, ContinuouslyStreaming) {
   GetAudioSink();
 
   media_endpoint_->SelectConfiguration(
       std::vector<uint8_t>({0x21, 0x15, 0x33, 0x2C}),
-      base::Bind(&BluetoothAudioSinkChromeOSTest::SelectConfigurationCallback,
+      base::Bind(&BluetoothAudioSinkBlueZTest::SelectConfigurationCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(audio_sink_->GetState(), BluetoothAudioSink::STATE_DISCONNECTED);
@@ -957,4 +942,4 @@
   EXPECT_EQ(observer_->total_read_, data_one.size() + data_two.size());
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_chromeos_unittest.cc b/device/bluetooth/bluetooth_bluez_unittest.cc
similarity index 88%
rename from device/bluetooth/bluetooth_chromeos_unittest.cc
rename to device/bluetooth/bluetooth_bluez_unittest.cc
index cea92d9..315a704 100644
--- a/device/bluetooth/bluetooth_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_bluez_unittest.cc
@@ -8,12 +8,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_device.h"
-#include "device/bluetooth/bluetooth_device_chromeos.h"
+#include "device/bluetooth/bluetooth_device_bluez.h"
 #include "device/bluetooth/bluetooth_discovery_session.h"
-#include "device/bluetooth/bluetooth_pairing_chromeos.h"
+#include "device/bluetooth/bluetooth_pairing_bluez.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
 #include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
@@ -33,7 +33,7 @@
 using device::BluetoothUUID;
 using device::TestBluetoothAdapterObserver;
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -163,7 +163,7 @@
   }
 };
 
-class BluetoothChromeOSTest : public testing::Test {
+class BluetoothBlueZTest : public testing::Test {
  public:
   void SetUp() override {
     scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
@@ -199,9 +199,8 @@
 
   void TearDown() override {
     for (ScopedVector<BluetoothDiscoverySession>::iterator iter =
-            discovery_sessions_.begin();
-         iter != discovery_sessions_.end();
-         ++iter) {
+             discovery_sessions_.begin();
+         iter != discovery_sessions_.end(); ++iter) {
       BluetoothDiscoverySession* session = *iter;
       if (!session->IsActive())
         continue;
@@ -222,7 +221,7 @@
   }
 
   base::Closure GetCallback() {
-    return base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this));
+    return base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this));
   }
 
   void DiscoverySessionCallback(
@@ -237,7 +236,7 @@
     QuitMessageLoop();
   }
 
-  void ProfileRegisteredCallback(BluetoothAdapterProfileChromeOS* profile) {
+  void ProfileRegisteredCallback(BluetoothAdapterProfileBlueZ* profile) {
     adapter_profile_ = profile;
     ++callback_count_;
     QuitMessageLoop();
@@ -253,13 +252,13 @@
   }
 
   base::Closure GetErrorCallback() {
-    return base::Bind(&BluetoothChromeOSTest::ErrorCallback,
+    return base::Bind(&BluetoothBlueZTest::ErrorCallback,
                       base::Unretained(this));
   }
 
   base::Callback<void(device::UMABluetoothDiscoverySessionOutcome)>
   GetDiscoveryErrorCallback() {
-    return base::Bind(&BluetoothChromeOSTest::DiscoveryErrorCallback,
+    return base::Bind(&BluetoothBlueZTest::DiscoveryErrorCallback,
                       base::Unretained(this));
   }
 
@@ -287,7 +286,7 @@
 
   // Call to fill the adapter_ member with a BluetoothAdapter instance.
   void GetAdapter() {
-    adapter_ = new BluetoothAdapterChromeOS();
+    adapter_ = new BluetoothAdapterBlueZ();
     ASSERT_TRUE(adapter_.get() != nullptr);
     ASSERT_TRUE(adapter_->IsInitialized());
   }
@@ -306,7 +305,7 @@
 
     adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
     adapter_->StartDiscoverySession(
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
         GetErrorCallback());
     base::MessageLoop::current()->Run();
@@ -350,7 +349,7 @@
   enum BluetoothDevice::ConnectErrorCode last_connect_error_;
   std::string last_client_error_;
   ScopedVector<BluetoothDiscoverySession> discovery_sessions_;
-  BluetoothAdapterProfileChromeOS* adapter_profile_;
+  BluetoothAdapterProfileBlueZ* adapter_profile_;
 
  private:
   // Some tests use a message loop since background processing is simulated;
@@ -363,7 +362,7 @@
   }
 };
 
-TEST_F(BluetoothChromeOSTest, AlreadyPresent) {
+TEST_F(BluetoothBlueZTest, AlreadyPresent) {
   GetAdapter();
 
   // This verifies that the class gets the list of adapters when created;
@@ -389,7 +388,7 @@
           bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress));
 }
 
-TEST_F(BluetoothChromeOSTest, BecomePresent) {
+TEST_F(BluetoothBlueZTest, BecomePresent) {
   fake_bluetooth_adapter_client_->SetVisible(false);
   GetAdapter();
   ASSERT_FALSE(adapter_->IsPresent());
@@ -417,7 +416,7 @@
   EXPECT_FALSE(adapter_->IsDiscovering());
 }
 
-TEST_F(BluetoothChromeOSTest, BecomeNotPresent) {
+TEST_F(BluetoothBlueZTest, BecomeNotPresent) {
   GetAdapter();
   ASSERT_TRUE(adapter_->IsPresent());
 
@@ -448,7 +447,7 @@
   EXPECT_FALSE(adapter_->IsDiscovering());
 }
 
-TEST_F(BluetoothChromeOSTest, SecondAdapter) {
+TEST_F(BluetoothBlueZTest, SecondAdapter) {
   GetAdapter();
   ASSERT_TRUE(adapter_->IsPresent());
 
@@ -499,7 +498,7 @@
   EXPECT_EQ(0, observer.discovering_changed_count());
 }
 
-TEST_F(BluetoothChromeOSTest, BecomePowered) {
+TEST_F(BluetoothBlueZTest, BecomePowered) {
   GetAdapter();
   ASSERT_FALSE(adapter_->IsPowered());
 
@@ -517,7 +516,7 @@
   EXPECT_TRUE(adapter_->IsPowered());
 }
 
-TEST_F(BluetoothChromeOSTest, BecomeNotPowered) {
+TEST_F(BluetoothBlueZTest, BecomeNotPowered) {
   GetAdapter();
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   EXPECT_EQ(1, callback_count_);
@@ -540,7 +539,7 @@
   EXPECT_FALSE(adapter_->IsPowered());
 }
 
-TEST_F(BluetoothChromeOSTest, SetPoweredWhenNotPresent) {
+TEST_F(BluetoothBlueZTest, SetPoweredWhenNotPresent) {
   GetAdapter();
   ASSERT_TRUE(adapter_->IsPresent());
 
@@ -566,7 +565,7 @@
   EXPECT_FALSE(adapter_->IsPowered());
 }
 
-TEST_F(BluetoothChromeOSTest, ChangeAdapterName) {
+TEST_F(BluetoothBlueZTest, ChangeAdapterName) {
   GetAdapter();
 
   static const std::string new_name(".__.");
@@ -578,7 +577,7 @@
   EXPECT_EQ(new_name, adapter_->GetName());
 }
 
-TEST_F(BluetoothChromeOSTest, ChangeAdapterNameWhenNotPresent) {
+TEST_F(BluetoothBlueZTest, ChangeAdapterNameWhenNotPresent) {
   GetAdapter();
   ASSERT_TRUE(adapter_->IsPresent());
 
@@ -601,7 +600,7 @@
   EXPECT_EQ("", adapter_->GetName());
 }
 
-TEST_F(BluetoothChromeOSTest, BecomeDiscoverable) {
+TEST_F(BluetoothBlueZTest, BecomeDiscoverable) {
   GetAdapter();
   ASSERT_FALSE(adapter_->IsDiscoverable());
 
@@ -618,7 +617,7 @@
   EXPECT_TRUE(adapter_->IsDiscoverable());
 }
 
-TEST_F(BluetoothChromeOSTest, BecomeNotDiscoverable) {
+TEST_F(BluetoothBlueZTest, BecomeNotDiscoverable) {
   GetAdapter();
   adapter_->SetDiscoverable(true, GetCallback(), GetErrorCallback());
   EXPECT_EQ(1, callback_count_);
@@ -640,7 +639,7 @@
   EXPECT_FALSE(adapter_->IsDiscoverable());
 }
 
-TEST_F(BluetoothChromeOSTest, SetDiscoverableWhenNotPresent) {
+TEST_F(BluetoothBlueZTest, SetDiscoverableWhenNotPresent) {
   GetAdapter();
   ASSERT_TRUE(adapter_->IsPresent());
   ASSERT_FALSE(adapter_->IsDiscoverable());
@@ -666,12 +665,12 @@
   EXPECT_FALSE(adapter_->IsDiscoverable());
 }
 
-TEST_F(BluetoothChromeOSTest, StopDiscovery) {
+TEST_F(BluetoothBlueZTest, StopDiscovery) {
   GetAdapter();
 
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();
@@ -705,7 +704,7 @@
   // BluetoothDiscoverySession objects gets deleted
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();
@@ -725,7 +724,7 @@
   EXPECT_EQ(0, error_callback_count_);
 }
 
-TEST_F(BluetoothChromeOSTest, Discovery) {
+TEST_F(BluetoothBlueZTest, Discovery) {
   // Test a simulated discovery session.
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
   GetAdapter();
@@ -734,7 +733,7 @@
 
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();
@@ -767,11 +766,11 @@
             observer.last_device_address());
 }
 
-TEST_F(BluetoothChromeOSTest, PoweredAndDiscovering) {
+TEST_F(BluetoothBlueZTest, PoweredAndDiscovering) {
   GetAdapter();
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();
@@ -833,7 +832,7 @@
 
 // This unit test asserts that the basic reference counting logic works
 // correctly for discovery requests done via the BluetoothAdapter.
-TEST_F(BluetoothChromeOSTest, MultipleDiscoverySessions) {
+TEST_F(BluetoothBlueZTest, MultipleDiscoverySessions) {
   GetAdapter();
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   EXPECT_EQ(1, callback_count_);
@@ -850,7 +849,7 @@
   // Request device discovery 3 times.
   for (int i = 0; i < 3; i++) {
     adapter_->StartDiscoverySession(
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
         GetErrorCallback());
   }
@@ -888,7 +887,7 @@
   // Request device discovery 3 times.
   for (int i = 0; i < 3; i++) {
     adapter_->StartDiscoverySession(
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
         GetErrorCallback());
   }
@@ -937,8 +936,7 @@
 // This unit test asserts that the reference counting logic works correctly in
 // the cases when the adapter gets reset and D-Bus calls are made outside of
 // the BluetoothAdapter.
-TEST_F(BluetoothChromeOSTest,
-       UnexpectedChangesDuringMultipleDiscoverySessions) {
+TEST_F(BluetoothBlueZTest, UnexpectedChangesDuringMultipleDiscoverySessions) {
   GetAdapter();
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   EXPECT_EQ(1, callback_count_);
@@ -955,7 +953,7 @@
   // Request device discovery 3 times.
   for (int i = 0; i < 3; i++) {
     adapter_->StartDiscoverySession(
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
         GetErrorCallback());
   }
@@ -992,7 +990,7 @@
   // bluez::FakeBluetoothAdapterClient::StopDiscovery should work.
   fake_bluetooth_adapter_client_->StopDiscovery(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                 base::Unretained(this)));
   message_loop_.Run();
   EXPECT_EQ(2, observer.discovering_changed_count());
@@ -1009,7 +1007,7 @@
   // It should be possible to successfully start discovery.
   for (int i = 0; i < 2; i++) {
     adapter_->StartDiscoverySession(
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
         GetErrorCallback());
   }
@@ -1057,7 +1055,7 @@
   // application other than us. Starting and stopping discovery will succeed
   // but it won't cause the discovery state to change.
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();  // Run the loop, as there should have been a D-Bus call.
@@ -1081,7 +1079,7 @@
 
   // Start discovery again.
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();  // Run the loop, as there should have been a D-Bus call.
@@ -1098,7 +1096,7 @@
   // requested it via D-Bus.
   fake_bluetooth_adapter_client_->StopDiscovery(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                 base::Unretained(this)));
   message_loop_.Run();
   EXPECT_EQ(5, observer.discovering_changed_count());
@@ -1119,7 +1117,7 @@
   EXPECT_FALSE(discovery_sessions_[0]->IsActive());
 }
 
-TEST_F(BluetoothChromeOSTest, InvalidatedDiscoverySessions) {
+TEST_F(BluetoothBlueZTest, InvalidatedDiscoverySessions) {
   GetAdapter();
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   EXPECT_EQ(1, callback_count_);
@@ -1136,7 +1134,7 @@
   // Request device discovery 3 times.
   for (int i = 0; i < 3; i++) {
     adapter_->StartDiscoverySession(
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
         GetErrorCallback());
   }
@@ -1176,7 +1174,7 @@
   // cleaned up.
   fake_bluetooth_adapter_client_->StopDiscovery(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                 base::Unretained(this)));
   message_loop_.Run();
   EXPECT_EQ(2, observer.discovering_changed_count());
@@ -1187,7 +1185,7 @@
   EXPECT_FALSE(discovery_sessions_[0]->IsActive());
 }
 
-TEST_F(BluetoothChromeOSTest, QueuedDiscoveryRequests) {
+TEST_F(BluetoothBlueZTest, QueuedDiscoveryRequests) {
   GetAdapter();
 
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
@@ -1204,7 +1202,7 @@
 
   // Request to start discovery. The call should be pending.
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   EXPECT_EQ(0, callback_count_);
@@ -1223,7 +1221,7 @@
   // be no change in state.
   for (int i = 0; i < 2; i++) {
     adapter_->StartDiscoverySession(
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
         GetErrorCallback());
   }
@@ -1269,7 +1267,7 @@
 
   // Request to start should get queued.
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   EXPECT_EQ(5, callback_count_);
@@ -1301,7 +1299,7 @@
   EXPECT_TRUE(discovery_sessions_[3]->IsActive());
 }
 
-TEST_F(BluetoothChromeOSTest, StartDiscoverySession) {
+TEST_F(BluetoothBlueZTest, StartDiscoverySession) {
   GetAdapter();
 
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
@@ -1319,7 +1317,7 @@
 
   // Request a new discovery session.
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();
@@ -1335,7 +1333,7 @@
   // in turn will destroy the previous session. Adapter should still be
   // discovering and the reference count should be 1.
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();
@@ -1349,7 +1347,7 @@
 
   // Request a new session.
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   message_loop_.Run();
@@ -1387,7 +1385,7 @@
   EXPECT_FALSE(adapter_->IsDiscovering());
 }
 
-TEST_F(BluetoothChromeOSTest, SetDiscoveryFilterBeforeStartDiscovery) {
+TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscovery) {
   // Test a simulated discovery session.
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
   GetAdapter();
@@ -1400,16 +1398,14 @@
   df->AddUUID(BluetoothUUID("1000"));
   scoped_ptr<BluetoothDiscoveryFilter> discovery_filter(df);
 
-  adapter_->SetPowered(true, base::Bind(&BluetoothChromeOSTest::Callback,
-                                        base::Unretained(this)),
-                       base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                                  base::Unretained(this)));
+  adapter_->SetPowered(
+      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
   message_loop_.Run();
   EXPECT_EQ(2, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1430,9 +1426,8 @@
   EXPECT_NE(uuids.end(), std::find(uuids.begin(), uuids.end(), "1000"));
 
   discovery_sessions_[0]->Stop(
-      base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -1450,7 +1445,7 @@
   EXPECT_EQ(nullptr, filter);
 }
 
-TEST_F(BluetoothChromeOSTest, SetDiscoveryFilterBeforeStartDiscoveryFail) {
+TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscoveryFail) {
   // Test a simulated discovery session.
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
   GetAdapter();
@@ -1463,10 +1458,9 @@
   df->AddUUID(BluetoothUUID("1000"));
   scoped_ptr<BluetoothDiscoveryFilter> discovery_filter(df);
 
-  adapter_->SetPowered(true, base::Bind(&BluetoothChromeOSTest::Callback,
-                                        base::Unretained(this)),
-                       base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                                  base::Unretained(this)));
+  adapter_->SetPowered(
+      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
   EXPECT_EQ(1, callback_count_);
   callback_count_ = 0;
 
@@ -1474,10 +1468,9 @@
 
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -1495,7 +1488,7 @@
 // This test queues two requests to StartDiscovery with pre set filter. This
 // should result in SetDiscoveryFilter, then StartDiscovery, and SetDiscovery
 // DBus calls
-TEST_F(BluetoothChromeOSTest, QueuedSetDiscoveryFilterBeforeStartDiscovery) {
+TEST_F(BluetoothBlueZTest, QueuedSetDiscoveryFilterBeforeStartDiscovery) {
   // Test a simulated discovery session.
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
   GetAdapter();
@@ -1514,10 +1507,9 @@
   df2->AddUUID(BluetoothUUID("1002"));
   scoped_ptr<BluetoothDiscoveryFilter> discovery_filter2(df2);
 
-  adapter_->SetPowered(true, base::Bind(&BluetoothChromeOSTest::Callback,
-                                        base::Unretained(this)),
-                       base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                                  base::Unretained(this)));
+  adapter_->SetPowered(
+      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   EXPECT_EQ(1, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1526,17 +1518,15 @@
   // Queue two requests to start discovery session with filter.
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter2.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   // Run requests, on DBus level there should be call SetDiscoveryFilter, then
   // StartDiscovery, then SetDiscoveryFilter again.
@@ -1565,14 +1555,12 @@
   EXPECT_NE(uuids.end(), std::find(uuids.begin(), uuids.end(), "1002"));
 
   discovery_sessions_[0]->Stop(
-      base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   discovery_sessions_[1]->Stop(
-      base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -1595,8 +1583,7 @@
 // Call StartFilteredDiscovery twice (2nd time while 1st call is still pending).
 // Make the first SetDiscoveryFilter fail and the second one succeed. It should
 // end up with one active discovery session.
-TEST_F(BluetoothChromeOSTest,
-       QueuedSetDiscoveryFilterBeforeStartDiscoveryFail) {
+TEST_F(BluetoothBlueZTest, QueuedSetDiscoveryFilterBeforeStartDiscoveryFail) {
   // Test a simulated discovery session.
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
   GetAdapter();
@@ -1615,10 +1602,9 @@
   df2->AddUUID(BluetoothUUID("1002"));
   scoped_ptr<BluetoothDiscoveryFilter> discovery_filter2(df2);
 
-  adapter_->SetPowered(true, base::Bind(&BluetoothChromeOSTest::Callback,
-                                        base::Unretained(this)),
-                       base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                                  base::Unretained(this)));
+  adapter_->SetPowered(
+      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   EXPECT_EQ(1, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1629,17 +1615,15 @@
   // Queue two requests to start discovery session with filter.
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter2.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -1674,9 +1658,8 @@
   EXPECT_NE(uuids.end(), std::find(uuids.begin(), uuids.end(), "1002"));
 
   discovery_sessions_[0]->Stop(
-      base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -1693,22 +1676,20 @@
   EXPECT_EQ(nullptr, filter);
 }
 
-TEST_F(BluetoothChromeOSTest, SetDiscoveryFilterAfterStartDiscovery) {
+TEST_F(BluetoothBlueZTest, SetDiscoveryFilterAfterStartDiscovery) {
   // Test a simulated discovery session.
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
   GetAdapter();
 
   TestBluetoothAdapterObserver observer(adapter_);
 
-  adapter_->SetPowered(true, base::Bind(&BluetoothChromeOSTest::Callback,
-                                        base::Unretained(this)),
-                       base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                                  base::Unretained(this)));
+  adapter_->SetPowered(
+      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
   message_loop_.Run();
   EXPECT_EQ(2, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1736,9 +1717,8 @@
 
   discovery_sessions_[0]->SetDiscoveryFilter(
       discovery_filter.Pass(),
-      base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
   EXPECT_EQ(1, callback_count_);
@@ -1756,9 +1736,8 @@
   EXPECT_NE(uuids.end(), std::find(uuids.begin(), uuids.end(), "1000"));
 
   discovery_sessions_[0]->Stop(
-      base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -1778,12 +1757,11 @@
 
 // This unit test asserts that the basic reference counting, and filter merging
 // works correctly for discovery requests done via the BluetoothAdapter.
-TEST_F(BluetoothChromeOSTest, SetDiscoveryFilterBeforeStartDiscoveryMultiple) {
+TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscoveryMultiple) {
   GetAdapter();
-  adapter_->SetPowered(true, base::Bind(&BluetoothChromeOSTest::Callback,
-                                        base::Unretained(this)),
-                       base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                                  base::Unretained(this)));
+  adapter_->SetPowered(
+      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
   EXPECT_EQ(1, callback_count_);
   EXPECT_EQ(0, error_callback_count_);
   EXPECT_TRUE(adapter_->IsPowered());
@@ -1818,10 +1796,9 @@
 
     adapter_->StartDiscoverySessionWithFilter(
         discovery_filter.Pass(),
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
-        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                   base::Unretained(this)));
+        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
     message_loop_.Run();
 
@@ -1868,9 +1845,8 @@
   // Request to stop discovery twice.
   for (int i = 0; i < 2; i++) {
     discovery_sessions_[i]->Stop(
-        base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                   base::Unretained(this)));
+        base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
     message_loop_.Run();
 
     if (i == 0) {
@@ -1944,10 +1920,9 @@
 
     adapter_->StartDiscoverySessionWithFilter(
         discovery_filter.Pass(),
-        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                    base::Unretained(this)),
-        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                   base::Unretained(this)));
+        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
     // each result in 1 requests.
     message_loop_.Run();
@@ -1985,9 +1960,8 @@
   // Request to stop discovery 4 times.
   for (int i = 2; i < 6; i++) {
     discovery_sessions_[i]->Stop(
-        base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                   base::Unretained(this)));
+        base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
     // filter no  2 is same as filter no 5, so removing it shouldn't cause any
     // filter update
@@ -2014,12 +1988,11 @@
 
 // This unit test asserts that filter merging logic works correctly for filtered
 // discovery requests done via the BluetoothAdapter.
-TEST_F(BluetoothChromeOSTest, SetDiscoveryFilterMergingTest) {
+TEST_F(BluetoothBlueZTest, SetDiscoveryFilterMergingTest) {
   GetAdapter();
-  adapter_->SetPowered(true, base::Bind(&BluetoothChromeOSTest::Callback,
-                                        base::Unretained(this)),
-                       base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                                  base::Unretained(this)));
+  adapter_->SetPowered(
+      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   BluetoothDiscoveryFilter* df = new BluetoothDiscoveryFilter(
       BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
@@ -2029,10 +2002,9 @@
 
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -2052,10 +2024,9 @@
 
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -2077,10 +2048,9 @@
 
   adapter_->StartDiscoverySessionWithFilter(
       discovery_filter3.Pass(),
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -2096,10 +2066,9 @@
 
   // start additionally classic scan
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -2112,16 +2081,15 @@
   // Request to stop discovery 4 times.
   for (int i = 3; i >= 0; i--) {
     discovery_sessions_[i]->Stop(
-        base::Bind(&BluetoothChromeOSTest::Callback, base::Unretained(this)),
-        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
-                   base::Unretained(this)));
+        base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
+        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
 
     // Every session stopping would trigger filter update
     message_loop_.Run();
   }
 }
 
-TEST_F(BluetoothChromeOSTest, DeviceProperties) {
+TEST_F(BluetoothBlueZTest, DeviceProperties) {
   GetAdapter();
 
   BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
@@ -2156,7 +2124,7 @@
   EXPECT_EQ(0x0306, devices[idx]->GetDeviceID());
 }
 
-TEST_F(BluetoothChromeOSTest, DeviceClassChanged) {
+TEST_F(BluetoothBlueZTest, DeviceClassChanged) {
   // Simulate a change of class of a device, as sometimes occurs
   // during discovery.
   GetAdapter();
@@ -2185,7 +2153,7 @@
   EXPECT_EQ(BluetoothDevice::DEVICE_MOUSE, devices[idx]->GetDeviceType());
 }
 
-TEST_F(BluetoothChromeOSTest, DeviceNameChanged) {
+TEST_F(BluetoothBlueZTest, DeviceNameChanged) {
   // Simulate a change of name of a device.
   GetAdapter();
 
@@ -2218,7 +2186,7 @@
   EXPECT_EQ(base::UTF8ToUTF16(new_name), devices[idx]->GetName());
 }
 
-TEST_F(BluetoothChromeOSTest, DeviceAddressChanged) {
+TEST_F(BluetoothBlueZTest, DeviceAddressChanged) {
   // Simulate a change of address of a device.
   GetAdapter();
 
@@ -2252,7 +2220,7 @@
   EXPECT_EQ(std::string(kNewAddress), devices[idx]->GetAddress());
 }
 
-TEST_F(BluetoothChromeOSTest, DeviceUuidsChanged) {
+TEST_F(BluetoothBlueZTest, DeviceUuidsChanged) {
   // Simulate a change of advertised services of a device.
   GetAdapter();
 
@@ -2300,7 +2268,7 @@
   EXPECT_EQ(uuids[4], BluetoothUUID("110a"));
 }
 
-TEST_F(BluetoothChromeOSTest, DeviceInquiryRSSIInvalidated) {
+TEST_F(BluetoothBlueZTest, DeviceInquiryRSSIInvalidated) {
   // Simulate invalidation of inquiry RSSI of a device, as it occurs
   // when discovery is finished.
   GetAdapter();
@@ -2337,7 +2305,7 @@
   EXPECT_EQ(unknown_power, devices[idx]->GetInquiryRSSI());
 }
 
-TEST_F(BluetoothChromeOSTest, DeviceInquiryTxPowerInvalidated) {
+TEST_F(BluetoothBlueZTest, DeviceInquiryTxPowerInvalidated) {
   // Simulate invalidation of inquiry TxPower of a device, as it occurs
   // when discovery is finished.
   GetAdapter();
@@ -2374,7 +2342,7 @@
   EXPECT_EQ(unknown_power, devices[idx]->GetInquiryTxPower());
 }
 
-TEST_F(BluetoothChromeOSTest, ForgetDevice) {
+TEST_F(BluetoothBlueZTest, ForgetDevice) {
   GetAdapter();
 
   BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
@@ -2403,7 +2371,7 @@
   ASSERT_EQ(1U, devices.size());
 }
 
-TEST_F(BluetoothChromeOSTest, ForgetUnpairedDevice) {
+TEST_F(BluetoothBlueZTest, ForgetUnpairedDevice) {
   GetAdapter();
   DiscoverDevices();
 
@@ -2414,7 +2382,7 @@
 
   // Connect the device so it becomes trusted and remembered.
   device->Connect(nullptr, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   ASSERT_EQ(1, callback_count_);
@@ -2447,7 +2415,7 @@
   EXPECT_FALSE(device != nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, ConnectPairedDevice) {
+TEST_F(BluetoothBlueZTest, ConnectPairedDevice) {
   GetAdapter();
 
   BluetoothDevice* device = adapter_->GetDevice(
@@ -2460,7 +2428,7 @@
   // Connect without a pairing delegate; since the device is already Paired
   // this should succeed and the device should become connected.
   device->Connect(nullptr, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, callback_count_);
@@ -2475,7 +2443,7 @@
   EXPECT_FALSE(device->IsConnecting());
 }
 
-TEST_F(BluetoothChromeOSTest, ConnectUnpairableDevice) {
+TEST_F(BluetoothBlueZTest, ConnectUnpairableDevice) {
   GetAdapter();
   DiscoverDevices();
 
@@ -2489,7 +2457,7 @@
   // Connect without a pairing delegate; since the device does not require
   // pairing, this should succeed and the device should become connected.
   device->Connect(nullptr, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, callback_count_);
@@ -2516,7 +2484,7 @@
   EXPECT_FALSE(device->IsConnectable());
 }
 
-TEST_F(BluetoothChromeOSTest, ConnectConnectedDevice) {
+TEST_F(BluetoothBlueZTest, ConnectConnectedDevice) {
   GetAdapter();
 
   BluetoothDevice* device = adapter_->GetDevice(
@@ -2525,7 +2493,7 @@
   ASSERT_TRUE(device->IsPaired());
 
   device->Connect(nullptr, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   ASSERT_EQ(1, callback_count_);
@@ -2539,7 +2507,7 @@
   TestBluetoothAdapterObserver observer(adapter_);
 
   device->Connect(nullptr, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, callback_count_);
@@ -2553,7 +2521,7 @@
   EXPECT_FALSE(device->IsConnecting());
 }
 
-TEST_F(BluetoothChromeOSTest, ConnectDeviceFails) {
+TEST_F(BluetoothBlueZTest, ConnectDeviceFails) {
   GetAdapter();
   DiscoverDevices();
 
@@ -2567,7 +2535,7 @@
   // Connect without a pairing delegate; since the device requires pairing,
   // this should fail with an error.
   device->Connect(nullptr, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(0, callback_count_);
@@ -2580,7 +2548,7 @@
   EXPECT_FALSE(device->IsConnecting());
 }
 
-TEST_F(BluetoothChromeOSTest, DisconnectDevice) {
+TEST_F(BluetoothBlueZTest, DisconnectDevice) {
   GetAdapter();
 
   BluetoothDevice* device = adapter_->GetDevice(
@@ -2589,7 +2557,7 @@
   ASSERT_TRUE(device->IsPaired());
 
   device->Connect(nullptr, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   ASSERT_EQ(1, callback_count_);
@@ -2614,7 +2582,7 @@
   EXPECT_FALSE(device->IsConnected());
 }
 
-TEST_F(BluetoothChromeOSTest, DisconnectUnconnectedDevice) {
+TEST_F(BluetoothBlueZTest, DisconnectUnconnectedDevice) {
   GetAdapter();
 
   BluetoothDevice* device = adapter_->GetDevice(
@@ -2637,7 +2605,7 @@
   EXPECT_FALSE(device->IsConnected());
 }
 
-TEST_F(BluetoothChromeOSTest, PairTrustedDevice) {
+TEST_F(BluetoothBlueZTest, PairTrustedDevice) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
   GetAdapter();
 
@@ -2667,7 +2635,7 @@
   adapter_->AddPairingDelegate(
       &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
   device->Pair(&pairing_delegate, GetCallback(),
-               base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+               base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                           base::Unretained(this)));
   EXPECT_EQ(1, pairing_delegate.call_count_);
   EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
@@ -2685,7 +2653,7 @@
   EXPECT_TRUE(properties->paired.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairAlreadyPairedDevice) {
+TEST_F(BluetoothBlueZTest, PairAlreadyPairedDevice) {
   GetAdapter();
 
   fake_bluetooth_device_client_->CreateDevice(
@@ -2708,7 +2676,7 @@
   adapter_->AddPairingDelegate(
       &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
   device->Pair(&pairing_delegate, GetCallback(),
-               base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+               base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                           base::Unretained(this)));
 
   // For already paired devices a call to |Pair| should succeed without calling
@@ -2718,7 +2686,7 @@
   EXPECT_EQ(0, error_callback_count_);
 }
 
-TEST_F(BluetoothChromeOSTest, PairLegacyAutopair) {
+TEST_F(BluetoothBlueZTest, PairLegacyAutopair) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -2735,7 +2703,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -2770,7 +2738,7 @@
   EXPECT_TRUE(properties->trusted.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairDisplayPinCode) {
+TEST_F(BluetoothBlueZTest, PairDisplayPinCode) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -2786,7 +2754,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -2823,7 +2791,7 @@
   EXPECT_TRUE(properties->trusted.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairDisplayPasskey) {
+TEST_F(BluetoothBlueZTest, PairDisplayPasskey) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -2840,7 +2808,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   // One call for DisplayPasskey() and one for KeysEntered().
@@ -2898,7 +2866,7 @@
   EXPECT_TRUE(properties->trusted.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairRequestPinCode) {
+TEST_F(BluetoothBlueZTest, PairRequestPinCode) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -2914,7 +2882,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -2952,7 +2920,7 @@
   EXPECT_TRUE(properties->trusted.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairConfirmPasskey) {
+TEST_F(BluetoothBlueZTest, PairConfirmPasskey) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -2968,7 +2936,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3003,7 +2971,7 @@
   EXPECT_TRUE(properties->trusted.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairRequestPasskey) {
+TEST_F(BluetoothBlueZTest, PairRequestPasskey) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3020,7 +2988,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3054,7 +3022,7 @@
   EXPECT_TRUE(properties->trusted.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairJustWorks) {
+TEST_F(BluetoothBlueZTest, PairJustWorks) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3071,7 +3039,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3101,7 +3069,7 @@
   EXPECT_TRUE(properties->trusted.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairUnpairableDeviceFails) {
+TEST_F(BluetoothBlueZTest, PairUnpairableDeviceFails) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3116,7 +3084,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3135,7 +3103,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingFails) {
+TEST_F(BluetoothBlueZTest, PairingFails) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3151,7 +3119,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3170,7 +3138,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingFailsAtConnection) {
+TEST_F(BluetoothBlueZTest, PairingFailsAtConnection) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3187,7 +3155,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3217,7 +3185,7 @@
   EXPECT_TRUE(properties->trusted.value());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingRejectedAtPinCode) {
+TEST_F(BluetoothBlueZTest, PairingRejectedAtPinCode) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3233,7 +3201,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3255,7 +3223,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingCancelledAtPinCode) {
+TEST_F(BluetoothBlueZTest, PairingCancelledAtPinCode) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3271,7 +3239,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3293,7 +3261,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingRejectedAtPasskey) {
+TEST_F(BluetoothBlueZTest, PairingRejectedAtPasskey) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3309,7 +3277,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3331,7 +3299,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingCancelledAtPasskey) {
+TEST_F(BluetoothBlueZTest, PairingCancelledAtPasskey) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3347,7 +3315,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3369,7 +3337,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingRejectedAtConfirmation) {
+TEST_F(BluetoothBlueZTest, PairingRejectedAtConfirmation) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3385,7 +3353,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3407,7 +3375,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingCancelledAtConfirmation) {
+TEST_F(BluetoothBlueZTest, PairingCancelledAtConfirmation) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3423,7 +3391,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3445,7 +3413,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, PairingCancelledInFlight) {
+TEST_F(BluetoothBlueZTest, PairingCancelledInFlight) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3461,7 +3429,7 @@
 
   TestPairingDelegate pairing_delegate;
   device->Connect(&pairing_delegate, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
 
   EXPECT_EQ(0, pairing_delegate.call_count_);
@@ -3482,15 +3450,14 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, IncomingPairRequestPinCode) {
+TEST_F(BluetoothBlueZTest, IncomingPairRequestPinCode) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
 
   TestPairingDelegate pairing_delegate;
   adapter_->AddPairingDelegate(
-      &pairing_delegate,
-      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
+      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
 
   // Requires that we provide a PIN code.
   fake_bluetooth_device_client_->CreateDevice(
@@ -3505,7 +3472,7 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath),
-      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                       base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3531,20 +3498,19 @@
   ASSERT_TRUE(properties->trusted.value());
 
   // No pairing context should remain on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, IncomingPairConfirmPasskey) {
+TEST_F(BluetoothBlueZTest, IncomingPairConfirmPasskey) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
 
   TestPairingDelegate pairing_delegate;
   adapter_->AddPairingDelegate(
-      &pairing_delegate,
-      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
+      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
 
   // Requests that we confirm a displayed passkey.
   fake_bluetooth_device_client_->CreateDevice(
@@ -3559,7 +3525,7 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath),
-      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                       base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3586,20 +3552,19 @@
   ASSERT_TRUE(properties->trusted.value());
 
   // No pairing context should remain on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, IncomingPairRequestPasskey) {
+TEST_F(BluetoothBlueZTest, IncomingPairRequestPasskey) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
 
   TestPairingDelegate pairing_delegate;
   adapter_->AddPairingDelegate(
-      &pairing_delegate,
-      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
+      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
 
   // Requests that we provide a Passkey.
   fake_bluetooth_device_client_->CreateDevice(
@@ -3614,7 +3579,7 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
-      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                       base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3640,20 +3605,19 @@
   ASSERT_TRUE(properties->trusted.value());
 
   // No pairing context should remain on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, IncomingPairJustWorks) {
+TEST_F(BluetoothBlueZTest, IncomingPairJustWorks) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
 
   TestPairingDelegate pairing_delegate;
   adapter_->AddPairingDelegate(
-      &pairing_delegate,
-      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
+      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
 
   // Uses just-works pairing so, sinec this an incoming pairing, require
   // authorization from the user.
@@ -3669,7 +3633,7 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                 base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
@@ -3695,12 +3659,12 @@
   ASSERT_TRUE(properties->trusted.value());
 
   // No pairing context should remain on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, IncomingPairRequestPinCodeWithoutDelegate) {
+TEST_F(BluetoothBlueZTest, IncomingPairRequestPinCodeWithoutDelegate) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3719,7 +3683,7 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath),
-      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                       base::Unretained(this)));
 
   message_loop_.Run();
@@ -3734,12 +3698,12 @@
   EXPECT_FALSE(device->IsPaired());
 
   // No pairing context should remain on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, IncomingPairConfirmPasskeyWithoutDelegate) {
+TEST_F(BluetoothBlueZTest, IncomingPairConfirmPasskeyWithoutDelegate) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3758,7 +3722,7 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath),
-      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                       base::Unretained(this)));
 
   message_loop_.Run();
@@ -3773,12 +3737,12 @@
   EXPECT_FALSE(device->IsPaired());
 
   // No pairing context should remain on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, IncomingPairRequestPasskeyWithoutDelegate) {
+TEST_F(BluetoothBlueZTest, IncomingPairRequestPasskeyWithoutDelegate) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3797,7 +3761,7 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
-      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                       base::Unretained(this)));
 
   message_loop_.Run();
@@ -3812,12 +3776,12 @@
   EXPECT_FALSE(device->IsPaired());
 
   // No pairing context should remain on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, IncomingPairJustWorksWithoutDelegate) {
+TEST_F(BluetoothBlueZTest, IncomingPairJustWorksWithoutDelegate) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
@@ -3836,7 +3800,7 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath), true,
-      GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                 base::Unretained(this)));
 
   message_loop_.Run();
@@ -3851,20 +3815,19 @@
   EXPECT_FALSE(device->IsPaired());
 
   // No pairing context should remain on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 }
 
-TEST_F(BluetoothChromeOSTest, RemovePairingDelegateDuringPairing) {
+TEST_F(BluetoothBlueZTest, RemovePairingDelegateDuringPairing) {
   fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
 
   GetAdapter();
 
   TestPairingDelegate pairing_delegate;
   adapter_->AddPairingDelegate(
-      &pairing_delegate,
-      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
+      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
 
   // Requests that we provide a Passkey.
   fake_bluetooth_device_client_->CreateDevice(
@@ -3879,21 +3842,21 @@
 
   fake_bluetooth_device_client_->SimulatePairing(
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
-      true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
+      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                       base::Unretained(this)));
 
   EXPECT_EQ(1, pairing_delegate.call_count_);
   EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
 
   // A pairing context should now be set on the device.
-  BluetoothDeviceChromeOS* device_chromeos =
-      static_cast<BluetoothDeviceChromeOS*>(device);
-  ASSERT_TRUE(device_chromeos->GetPairing() != nullptr);
+  BluetoothDeviceBlueZ* device_bluez =
+      static_cast<BluetoothDeviceBlueZ*>(device);
+  ASSERT_TRUE(device_bluez->GetPairing() != nullptr);
 
   // Removing the pairing delegate should remove that pairing context.
   adapter_->RemovePairingDelegate(&pairing_delegate);
 
-  EXPECT_TRUE(device_chromeos->GetPairing() == nullptr);
+  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
 
   // Set the Passkey, this should now have no effect since the pairing has
   // been, in-effect, cancelled
@@ -3906,7 +3869,7 @@
   EXPECT_FALSE(device->IsPaired());
 }
 
-TEST_F(BluetoothChromeOSTest, DeviceId) {
+TEST_F(BluetoothBlueZTest, DeviceId) {
   GetAdapter();
 
   // Use the built-in paired device for this test, grab its Properties
@@ -3961,7 +3924,7 @@
   EXPECT_EQ(0, device->GetDeviceID());
 }
 
-TEST_F(BluetoothChromeOSTest, GetConnectionInfoForDisconnectedDevice) {
+TEST_F(BluetoothBlueZTest, GetConnectionInfoForDisconnectedDevice) {
   GetAdapter();
   BluetoothDevice* device = adapter_->GetDevice(
       bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
@@ -3977,13 +3940,13 @@
   EXPECT_EQ(unknown_power, conn_info.max_transmit_power);
 }
 
-TEST_F(BluetoothChromeOSTest, GetConnectionInfoForConnectedDevice) {
+TEST_F(BluetoothBlueZTest, GetConnectionInfoForConnectedDevice) {
   GetAdapter();
   BluetoothDevice* device = adapter_->GetDevice(
       bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
 
   device->Connect(nullptr, GetCallback(),
-                  base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
+                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                              base::Unretained(this)));
   EXPECT_TRUE(device->IsConnected());
 
@@ -3998,13 +3961,13 @@
 }
 
 // Verifies Shutdown shuts down the adapter as expected.
-TEST_F(BluetoothChromeOSTest, Shutdown) {
+TEST_F(BluetoothBlueZTest, Shutdown) {
   // Set up adapter. Set powered & discoverable, start discovery.
   GetAdapter();
   adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
   adapter_->SetDiscoverable(true, GetCallback(), GetErrorCallback());
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   base::MessageLoop::current()->Run();
@@ -4028,13 +3991,13 @@
   EXPECT_NE(nullptr,
             adapter_->GetDevice(
                 bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress));
-  EXPECT_NE(dbus::ObjectPath(""), static_cast<BluetoothAdapterChromeOS*>(
-                                      adapter_.get())->object_path());
+  EXPECT_NE(dbus::ObjectPath(""),
+            static_cast<BluetoothAdapterBlueZ*>(adapter_.get())->object_path());
 
   // Shutdown
   adapter_->Shutdown();
 
-  // Validate post shutdown state by calling all BluetoothAdapterChromeOS
+  // Validate post shutdown state by calling all BluetoothAdapterBlueZ
   // members, in declaration order:
 
   adapter_->Shutdown();
@@ -4070,15 +4033,15 @@
   BluetoothAudioSink::Options audio_sink_options;
   adapter_->RegisterAudioSink(
       audio_sink_options,
-      base::Bind(&BluetoothChromeOSTest::AudioSinkAcquiredCallback,
+      base::Bind(&BluetoothBlueZTest::AudioSinkAcquiredCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::AudioSinkErrorCallback,
+      base::Bind(&BluetoothBlueZTest::AudioSinkErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(0, callback_count_);
   EXPECT_EQ(1, error_callback_count_--) << "RegisterAudioSink error";
 
-  BluetoothAdapterChromeOS* adapter_chrome_os =
-      static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
+  BluetoothAdapterBlueZ* adapter_chrome_os =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
   EXPECT_EQ(nullptr,
             adapter_chrome_os->GetDeviceWithPath(dbus::ObjectPath("")));
 
@@ -4105,9 +4068,9 @@
   adapter_chrome_os->UseProfile(
       BluetoothUUID(), dbus::ObjectPath(""),
       bluez::BluetoothProfileManagerClient::Options(), &profile_delegate,
-      base::Bind(&BluetoothChromeOSTest::ProfileRegisteredCallback,
+      base::Bind(&BluetoothBlueZTest::ProfileRegisteredCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
+      base::Bind(&BluetoothBlueZTest::ErrorCompletionCallback,
                  base::Unretained(this)));
 
   EXPECT_FALSE(adapter_profile_) << "UseProfile error";
@@ -4135,9 +4098,9 @@
   adapter_chrome_os->OnRequestDefaultAgentError("", "");
 
   adapter_chrome_os->OnRegisterAudioSink(
-      base::Bind(&BluetoothChromeOSTest::AudioSinkAcquiredCallback,
+      base::Bind(&BluetoothBlueZTest::AudioSinkAcquiredCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::AudioSinkErrorCallback,
+      base::Bind(&BluetoothBlueZTest::AudioSinkErrorCallback,
                  base::Unretained(this)),
       scoped_refptr<device::BluetoothAudioSink>());
   EXPECT_EQ(0, callback_count_);
@@ -4183,9 +4146,9 @@
   adapter_chrome_os->UseProfile(
       BluetoothUUID(), dbus::ObjectPath(""),
       bluez::BluetoothProfileManagerClient::Options(), &profile_delegate,
-      base::Bind(&BluetoothChromeOSTest::ProfileRegisteredCallback,
+      base::Bind(&BluetoothBlueZTest::ProfileRegisteredCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
+      base::Bind(&BluetoothBlueZTest::ErrorCompletionCallback,
                  base::Unretained(this)));
 
   EXPECT_FALSE(adapter_profile_) << "UseProfile error";
@@ -4194,9 +4157,9 @@
 
   adapter_chrome_os->SetProfileDelegate(
       BluetoothUUID(), dbus::ObjectPath(""), &profile_delegate,
-      base::Bind(&BluetoothChromeOSTest::ProfileRegisteredCallback,
+      base::Bind(&BluetoothBlueZTest::ProfileRegisteredCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
+      base::Bind(&BluetoothBlueZTest::ErrorCompletionCallback,
                  base::Unretained(this)));
   EXPECT_EQ(0, callback_count_) << "SetProfileDelegate error";
   EXPECT_EQ(1, error_callback_count_--) << "SetProfileDelegate error";
@@ -4210,7 +4173,7 @@
   // From BluetoothAdapater:
 
   adapter_->StartDiscoverySession(
-      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
+      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                  base::Unretained(this)),
       GetErrorCallback());
   EXPECT_EQ(0, callback_count_) << "StartDiscoverySession error";
@@ -4227,11 +4190,11 @@
 }
 
 // Verifies post-Shutdown of discovery sessions and OnStartDiscovery.
-TEST_F(BluetoothChromeOSTest, Shutdown_OnStartDiscovery) {
+TEST_F(BluetoothBlueZTest, Shutdown_OnStartDiscovery) {
   const int kNumberOfDiscoverySessions = 10;
   GetAdapter();
-  BluetoothAdapterChromeOS* adapter_chrome_os =
-      static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
+  BluetoothAdapterBlueZ* adapter_chrome_os =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
 
   for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
     adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
@@ -4246,11 +4209,11 @@
 }
 
 // Verifies post-Shutdown of discovery sessions and OnStartDiscoveryError.
-TEST_F(BluetoothChromeOSTest, Shutdown_OnStartDiscoveryError) {
+TEST_F(BluetoothBlueZTest, Shutdown_OnStartDiscoveryError) {
   const int kNumberOfDiscoverySessions = 10;
   GetAdapter();
-  BluetoothAdapterChromeOS* adapter_chrome_os =
-      static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
+  BluetoothAdapterBlueZ* adapter_chrome_os =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
 
   for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
     adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
@@ -4265,11 +4228,11 @@
 }
 
 // Verifies post-Shutdown of discovery sessions and OnStartDiscovery.
-TEST_F(BluetoothChromeOSTest, Shutdown_OnStopDiscovery) {
+TEST_F(BluetoothBlueZTest, Shutdown_OnStopDiscovery) {
   const int kNumberOfDiscoverySessions = 10;
   GetAdapter();
-  BluetoothAdapterChromeOS* adapter_chrome_os =
-      static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
+  BluetoothAdapterBlueZ* adapter_chrome_os =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
 
   // In order to queue up discovery sessions before an OnStopDiscovery call
   // RemoveDiscoverySession must be called, so Add, Start, and Remove:
@@ -4296,11 +4259,11 @@
 }
 
 // Verifies post-Shutdown of discovery sessions and OnStopDiscoveryError.
-TEST_F(BluetoothChromeOSTest, Shutdown_OnStopDiscoveryError) {
+TEST_F(BluetoothBlueZTest, Shutdown_OnStopDiscoveryError) {
   const int kNumberOfDiscoverySessions = 10;
   GetAdapter();
-  BluetoothAdapterChromeOS* adapter_chrome_os =
-      static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
+  BluetoothAdapterBlueZ* adapter_chrome_os =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
 
   // In order to queue up discovery sessions before an OnStopDiscoveryError call
   // RemoveDiscoverySession must be called, so Add, Start, and Remove:
@@ -4326,4 +4289,4 @@
   EXPECT_EQ(1 + kNumberOfDiscoverySessions, error_callback_count_);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_bluez.cc
similarity index 72%
rename from device/bluetooth/bluetooth_device_chromeos.cc
rename to device/bluetooth/bluetooth_device_bluez.cc
index ea4a168c..a2b056b4 100644
--- a/device/bluetooth/bluetooth_device_chromeos.cc
+++ b/device/bluetooth/bluetooth_device_bluez.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_device_chromeos.h"
+#include "device/bluetooth/bluetooth_device_bluez.h"
 
 #include <stdio.h>
 
@@ -12,12 +12,12 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "dbus/bus.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
-#include "device/bluetooth/bluetooth_gatt_connection_chromeos.h"
-#include "device/bluetooth/bluetooth_pairing_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
+#include "device/bluetooth/bluetooth_gatt_connection_bluez.h"
+#include "device/bluetooth/bluetooth_pairing_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h"
 #include "device/bluetooth/bluetooth_socket.h"
-#include "device/bluetooth/bluetooth_socket_chromeos.h"
+#include "device/bluetooth/bluetooth_socket_bluez.h"
 #include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 #include "device/bluetooth/dbus/bluetooth_adapter_client.h"
@@ -64,11 +64,11 @@
   BluetoothDevice::VendorIDSource source_value;
   int vendor_value, product_value, device_value;
 
-  if (sscanf(modalias.c_str(), "bluetooth:v%04xp%04xd%04x",
-             &vendor_value, &product_value, &device_value) == 3) {
+  if (sscanf(modalias.c_str(), "bluetooth:v%04xp%04xd%04x", &vendor_value,
+             &product_value, &device_value) == 3) {
     source_value = BluetoothDevice::VENDOR_ID_BLUETOOTH;
-  } else if (sscanf(modalias.c_str(), "usb:v%04xp%04xd%04x",
-                    &vendor_value, &product_value, &device_value) == 3) {
+  } else if (sscanf(modalias.c_str(), "usb:v%04xp%04xd%04x", &vendor_value,
+                    &product_value, &device_value) == 3) {
     source_value = BluetoothDevice::VENDOR_ID_USB;
   } else {
     return;
@@ -112,8 +112,7 @@
       pairing_result = UMA_PAIRING_RESULT_UNKNOWN_ERROR;
   }
 
-  UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult",
-                            pairing_result,
+  UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult", pairing_result,
                             UMA_PAIRING_RESULT_COUNT);
 }
 
@@ -138,10 +137,10 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
-BluetoothDeviceChromeOS::BluetoothDeviceChromeOS(
-    BluetoothAdapterChromeOS* adapter,
+BluetoothDeviceBlueZ::BluetoothDeviceBlueZ(
+    BluetoothAdapterBlueZ* adapter,
     const dbus::ObjectPath& object_path,
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
     scoped_refptr<device::BluetoothSocketThread> socket_thread)
@@ -166,7 +165,7 @@
   }
 }
 
-BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() {
+BluetoothDeviceBlueZ::~BluetoothDeviceBlueZ() {
   bluez::BluezDBusManager::Get()
       ->GetBluetoothGattServiceClient()
       ->RemoveObserver(this);
@@ -178,11 +177,11 @@
   for (const auto& iter : gatt_services_swapped) {
     DCHECK(adapter_);
     adapter()->NotifyGattServiceRemoved(
-        static_cast<BluetoothRemoteGattServiceChromeOS*>(iter.second));
+        static_cast<BluetoothRemoteGattServiceBlueZ*>(iter.second));
   }
 }
 
-uint32 BluetoothDeviceChromeOS::GetBluetoothClass() const {
+uint32 BluetoothDeviceBlueZ::GetBluetoothClass() const {
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
@@ -191,7 +190,7 @@
   return properties->bluetooth_class.value();
 }
 
-std::string BluetoothDeviceChromeOS::GetDeviceName() const {
+std::string BluetoothDeviceBlueZ::GetDeviceName() const {
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
@@ -200,19 +199,19 @@
   return properties->alias.value();
 }
 
-void BluetoothDeviceChromeOS::CreateGattConnectionImpl() {
-  // ChromeOS implementation does not use the default CreateGattConnection
+void BluetoothDeviceBlueZ::CreateGattConnectionImpl() {
+  // BlueZ implementation does not use the default CreateGattConnection
   // implementation.
   NOTIMPLEMENTED();
 }
 
-void BluetoothDeviceChromeOS::DisconnectGatt() {
-  // ChromeOS implementation does not use the default CreateGattConnection
+void BluetoothDeviceBlueZ::DisconnectGatt() {
+  // BlueZ implementation does not use the default CreateGattConnection
   // implementation.
   NOTIMPLEMENTED();
 }
 
-std::string BluetoothDeviceChromeOS::GetAddress() const {
+std::string BluetoothDeviceBlueZ::GetAddress() const {
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
@@ -221,32 +220,32 @@
   return CanonicalizeAddress(properties->address.value());
 }
 
-BluetoothDevice::VendorIDSource
-BluetoothDeviceChromeOS::GetVendorIDSource() const {
+BluetoothDevice::VendorIDSource BluetoothDeviceBlueZ::GetVendorIDSource()
+    const {
   VendorIDSource vendor_id_source = VENDOR_ID_UNKNOWN;
   ParseModalias(object_path_, &vendor_id_source, NULL, NULL, NULL);
   return vendor_id_source;
 }
 
-uint16 BluetoothDeviceChromeOS::GetVendorID() const {
-  uint16 vendor_id  = 0;
+uint16 BluetoothDeviceBlueZ::GetVendorID() const {
+  uint16 vendor_id = 0;
   ParseModalias(object_path_, NULL, &vendor_id, NULL, NULL);
   return vendor_id;
 }
 
-uint16 BluetoothDeviceChromeOS::GetProductID() const {
-  uint16 product_id  = 0;
+uint16 BluetoothDeviceBlueZ::GetProductID() const {
+  uint16 product_id = 0;
   ParseModalias(object_path_, NULL, NULL, &product_id, NULL);
   return product_id;
 }
 
-uint16 BluetoothDeviceChromeOS::GetDeviceID() const {
-  uint16 device_id  = 0;
+uint16 BluetoothDeviceBlueZ::GetDeviceID() const {
+  uint16 device_id = 0;
   ParseModalias(object_path_, NULL, NULL, NULL, &device_id);
   return device_id;
 }
 
-bool BluetoothDeviceChromeOS::IsPaired() const {
+bool BluetoothDeviceBlueZ::IsPaired() const {
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
@@ -258,7 +257,7 @@
   return properties->paired.value() || properties->trusted.value();
 }
 
-bool BluetoothDeviceChromeOS::IsConnected() const {
+bool BluetoothDeviceBlueZ::IsConnected() const {
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
@@ -267,12 +266,12 @@
   return properties->connected.value();
 }
 
-bool BluetoothDeviceChromeOS::IsGattConnected() const {
+bool BluetoothDeviceBlueZ::IsGattConnected() const {
   NOTIMPLEMENTED();
   return false;
 }
 
-bool BluetoothDeviceChromeOS::IsConnectable() const {
+bool BluetoothDeviceBlueZ::IsConnectable() const {
   bluez::BluetoothInputClient::Properties* input_properties =
       bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->GetProperties(
           object_path_);
@@ -284,18 +283,18 @@
   return input_properties->reconnect_mode.value() != "device";
 }
 
-bool BluetoothDeviceChromeOS::IsConnecting() const {
+bool BluetoothDeviceBlueZ::IsConnecting() const {
   return num_connecting_calls_ > 0;
 }
 
-BluetoothDeviceChromeOS::UUIDList BluetoothDeviceChromeOS::GetUUIDs() const {
+BluetoothDeviceBlueZ::UUIDList BluetoothDeviceBlueZ::GetUUIDs() const {
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
   DCHECK(properties);
 
   std::vector<device::BluetoothUUID> uuids;
-  const std::vector<std::string> &dbus_uuids = properties->uuids.value();
+  const std::vector<std::string>& dbus_uuids = properties->uuids.value();
   for (std::vector<std::string>::const_iterator iter = dbus_uuids.begin();
        iter != dbus_uuids.end(); ++iter) {
     device::BluetoothUUID uuid(*iter);
@@ -305,7 +304,7 @@
   return uuids;
 }
 
-int16 BluetoothDeviceChromeOS::GetInquiryRSSI() const {
+int16 BluetoothDeviceBlueZ::GetInquiryRSSI() const {
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
@@ -317,7 +316,7 @@
   return properties->rssi.value();
 }
 
-int16 BluetoothDeviceChromeOS::GetInquiryTxPower() const {
+int16 BluetoothDeviceBlueZ::GetInquiryTxPower() const {
   bluez::BluetoothDeviceClient::Properties* properties =
       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
           object_path_);
@@ -329,30 +328,30 @@
   return properties->tx_power.value();
 }
 
-bool BluetoothDeviceChromeOS::ExpectingPinCode() const {
+bool BluetoothDeviceBlueZ::ExpectingPinCode() const {
   return pairing_.get() && pairing_->ExpectingPinCode();
 }
 
-bool BluetoothDeviceChromeOS::ExpectingPasskey() const {
+bool BluetoothDeviceBlueZ::ExpectingPasskey() const {
   return pairing_.get() && pairing_->ExpectingPasskey();
 }
 
-bool BluetoothDeviceChromeOS::ExpectingConfirmation() const {
+bool BluetoothDeviceBlueZ::ExpectingConfirmation() const {
   return pairing_.get() && pairing_->ExpectingConfirmation();
 }
 
-void BluetoothDeviceChromeOS::GetConnectionInfo(
+void BluetoothDeviceBlueZ::GetConnectionInfo(
     const ConnectionInfoCallback& callback) {
   // DBus method call should gracefully return an error if the device is not
   // currently connected.
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetConnInfo(
-      object_path_, base::Bind(&BluetoothDeviceChromeOS::OnGetConnInfo,
+      object_path_, base::Bind(&BluetoothDeviceBlueZ::OnGetConnInfo,
                                weak_ptr_factory_.GetWeakPtr(), callback),
-      base::Bind(&BluetoothDeviceChromeOS::OnGetConnInfoError,
+      base::Bind(&BluetoothDeviceBlueZ::OnGetConnInfoError,
                  weak_ptr_factory_.GetWeakPtr(), callback));
 }
 
-void BluetoothDeviceChromeOS::Connect(
+void BluetoothDeviceBlueZ::Connect(
     BluetoothDevice::PairingDelegate* pairing_delegate,
     const base::Closure& callback,
     const ConnectErrorCallback& error_callback) {
@@ -371,14 +370,14 @@
 
     bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Pair(
         object_path_,
-        base::Bind(&BluetoothDeviceChromeOS::OnPairDuringConnect,
+        base::Bind(&BluetoothDeviceBlueZ::OnPairDuringConnect,
                    weak_ptr_factory_.GetWeakPtr(), callback, error_callback),
-        base::Bind(&BluetoothDeviceChromeOS::OnPairDuringConnectError,
+        base::Bind(&BluetoothDeviceBlueZ::OnPairDuringConnectError,
                    weak_ptr_factory_.GetWeakPtr(), error_callback));
   }
 }
 
-void BluetoothDeviceChromeOS::Pair(
+void BluetoothDeviceBlueZ::Pair(
     BluetoothDevice::PairingDelegate* pairing_delegate,
     const base::Closure& callback,
     const ConnectErrorCallback& error_callback) {
@@ -386,41 +385,41 @@
   BeginPairing(pairing_delegate);
 
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Pair(
-      object_path_, base::Bind(&BluetoothDeviceChromeOS::OnPair,
+      object_path_, base::Bind(&BluetoothDeviceBlueZ::OnPair,
                                weak_ptr_factory_.GetWeakPtr(), callback),
-      base::Bind(&BluetoothDeviceChromeOS::OnPairError,
+      base::Bind(&BluetoothDeviceBlueZ::OnPairError,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothDeviceChromeOS::SetPinCode(const std::string& pincode) {
+void BluetoothDeviceBlueZ::SetPinCode(const std::string& pincode) {
   if (!pairing_.get())
     return;
 
   pairing_->SetPinCode(pincode);
 }
 
-void BluetoothDeviceChromeOS::SetPasskey(uint32 passkey) {
+void BluetoothDeviceBlueZ::SetPasskey(uint32 passkey) {
   if (!pairing_.get())
     return;
 
   pairing_->SetPasskey(passkey);
 }
 
-void BluetoothDeviceChromeOS::ConfirmPairing() {
+void BluetoothDeviceBlueZ::ConfirmPairing() {
   if (!pairing_.get())
     return;
 
   pairing_->ConfirmPairing();
 }
 
-void BluetoothDeviceChromeOS::RejectPairing() {
+void BluetoothDeviceBlueZ::RejectPairing() {
   if (!pairing_.get())
     return;
 
   pairing_->RejectPairing();
 }
 
-void BluetoothDeviceChromeOS::CancelPairing() {
+void BluetoothDeviceBlueZ::CancelPairing() {
   bool canceled = false;
 
   // If there is a callback in progress that we can reply to then use that
@@ -434,7 +433,7 @@
             << "Sending explicit cancel";
     bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->CancelPairing(
         object_path_, base::Bind(&base::DoNothing),
-        base::Bind(&BluetoothDeviceChromeOS::OnCancelPairingError,
+        base::Bind(&BluetoothDeviceBlueZ::OnCancelPairingError,
                    weak_ptr_factory_.GetWeakPtr()));
   }
 
@@ -445,53 +444,53 @@
   EndPairing();
 }
 
-void BluetoothDeviceChromeOS::Disconnect(const base::Closure& callback,
-                                         const ErrorCallback& error_callback) {
+void BluetoothDeviceBlueZ::Disconnect(const base::Closure& callback,
+                                      const ErrorCallback& error_callback) {
   VLOG(1) << object_path_.value() << ": Disconnecting";
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Disconnect(
-      object_path_, base::Bind(&BluetoothDeviceChromeOS::OnDisconnect,
+      object_path_, base::Bind(&BluetoothDeviceBlueZ::OnDisconnect,
                                weak_ptr_factory_.GetWeakPtr(), callback),
-      base::Bind(&BluetoothDeviceChromeOS::OnDisconnectError,
+      base::Bind(&BluetoothDeviceBlueZ::OnDisconnectError,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothDeviceChromeOS::Forget(const ErrorCallback& error_callback) {
+void BluetoothDeviceBlueZ::Forget(const ErrorCallback& error_callback) {
   VLOG(1) << object_path_.value() << ": Removing device";
   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->RemoveDevice(
       adapter()->object_path(), object_path_, base::Bind(&base::DoNothing),
-      base::Bind(&BluetoothDeviceChromeOS::OnForgetError,
+      base::Bind(&BluetoothDeviceBlueZ::OnForgetError,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothDeviceChromeOS::ConnectToService(
+void BluetoothDeviceBlueZ::ConnectToService(
     const BluetoothUUID& uuid,
     const ConnectToServiceCallback& callback,
     const ConnectToServiceErrorCallback& error_callback) {
-  VLOG(1) << object_path_.value() << ": Connecting to service: "
-          << uuid.canonical_value();
-  scoped_refptr<BluetoothSocketChromeOS> socket =
-      BluetoothSocketChromeOS::CreateBluetoothSocket(
-          ui_task_runner_, socket_thread_);
-  socket->Connect(this, uuid, BluetoothSocketChromeOS::SECURITY_LEVEL_MEDIUM,
+  VLOG(1) << object_path_.value()
+          << ": Connecting to service: " << uuid.canonical_value();
+  scoped_refptr<BluetoothSocketBlueZ> socket =
+      BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner_,
+                                                  socket_thread_);
+  socket->Connect(this, uuid, BluetoothSocketBlueZ::SECURITY_LEVEL_MEDIUM,
                   base::Bind(callback, socket), error_callback);
 }
 
-void BluetoothDeviceChromeOS::ConnectToServiceInsecurely(
+void BluetoothDeviceBlueZ::ConnectToServiceInsecurely(
     const BluetoothUUID& uuid,
     const ConnectToServiceCallback& callback,
     const ConnectToServiceErrorCallback& error_callback) {
-  VLOG(1) << object_path_.value() << ": Connecting insecurely to service: "
-          << uuid.canonical_value();
-  scoped_refptr<BluetoothSocketChromeOS> socket =
-      BluetoothSocketChromeOS::CreateBluetoothSocket(
-          ui_task_runner_, socket_thread_);
-  socket->Connect(this, uuid, BluetoothSocketChromeOS::SECURITY_LEVEL_LOW,
+  VLOG(1) << object_path_.value()
+          << ": Connecting insecurely to service: " << uuid.canonical_value();
+  scoped_refptr<BluetoothSocketBlueZ> socket =
+      BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner_,
+                                                  socket_thread_);
+  socket->Connect(this, uuid, BluetoothSocketBlueZ::SECURITY_LEVEL_LOW,
                   base::Bind(callback, socket), error_callback);
 }
 
-void BluetoothDeviceChromeOS::CreateGattConnection(
-      const GattConnectionCallback& callback,
-      const ConnectErrorCallback& error_callback) {
+void BluetoothDeviceBlueZ::CreateGattConnection(
+    const GattConnectionCallback& callback,
+    const ConnectErrorCallback& error_callback) {
   // TODO(sacomoto): Workaround to retrieve the connection for already connected
   // devices. Currently, BluetoothGattConnection::Disconnect doesn't do
   // anything, the unique underlying physical GATT connection is kept. This
@@ -504,32 +503,30 @@
 
   // TODO(armansito): Until there is a way to create a reference counted GATT
   // connection in bluetoothd, simply do a regular connect.
-  Connect(NULL,
-          base::Bind(&BluetoothDeviceChromeOS::OnCreateGattConnection,
-                     weak_ptr_factory_.GetWeakPtr(),
-                     callback),
+  Connect(NULL, base::Bind(&BluetoothDeviceBlueZ::OnCreateGattConnection,
+                           weak_ptr_factory_.GetWeakPtr(), callback),
           error_callback);
 }
 
-BluetoothPairingChromeOS* BluetoothDeviceChromeOS::BeginPairing(
+BluetoothPairingBlueZ* BluetoothDeviceBlueZ::BeginPairing(
     BluetoothDevice::PairingDelegate* pairing_delegate) {
-  pairing_.reset(new BluetoothPairingChromeOS(this, pairing_delegate));
+  pairing_.reset(new BluetoothPairingBlueZ(this, pairing_delegate));
   return pairing_.get();
 }
 
-void BluetoothDeviceChromeOS::EndPairing() {
+void BluetoothDeviceBlueZ::EndPairing() {
   pairing_.reset();
 }
 
-BluetoothPairingChromeOS* BluetoothDeviceChromeOS::GetPairing() const {
+BluetoothPairingBlueZ* BluetoothDeviceBlueZ::GetPairing() const {
   return pairing_.get();
 }
 
-BluetoothAdapterChromeOS* BluetoothDeviceChromeOS::adapter() const {
-  return static_cast<BluetoothAdapterChromeOS*>(adapter_);
+BluetoothAdapterBlueZ* BluetoothDeviceBlueZ::adapter() const {
+  return static_cast<BluetoothAdapterBlueZ*>(adapter_);
 }
 
-void BluetoothDeviceChromeOS::GattServiceAdded(
+void BluetoothDeviceBlueZ::GattServiceAdded(
     const dbus::ObjectPath& object_path) {
   if (GetGattService(object_path.value())) {
     VLOG(1) << "Remote GATT service already exists: " << object_path.value();
@@ -548,8 +545,8 @@
 
   VLOG(1) << "Adding new remote GATT service for device: " << GetAddress();
 
-  BluetoothRemoteGattServiceChromeOS* service =
-      new BluetoothRemoteGattServiceChromeOS(adapter(), this, object_path);
+  BluetoothRemoteGattServiceBlueZ* service =
+      new BluetoothRemoteGattServiceBlueZ(adapter(), this, object_path);
 
   gatt_services_.set(service->GetIdentifier(),
                      scoped_ptr<BluetoothGattService>(service));
@@ -560,7 +557,7 @@
   adapter()->NotifyGattServiceAdded(service);
 }
 
-void BluetoothDeviceChromeOS::GattServiceRemoved(
+void BluetoothDeviceBlueZ::GattServiceRemoved(
     const dbus::ObjectPath& object_path) {
   GattServiceMap::const_iterator iter =
       gatt_services_.find(object_path.value());
@@ -569,8 +566,8 @@
     return;
   }
 
-  BluetoothRemoteGattServiceChromeOS* service =
-      static_cast<BluetoothRemoteGattServiceChromeOS*>(iter->second);
+  BluetoothRemoteGattServiceBlueZ* service =
+      static_cast<BluetoothRemoteGattServiceBlueZ*>(iter->second);
 
   VLOG(1) << "Removing remote GATT service with UUID: '"
           << service->GetUUID().canonical_value()
@@ -584,15 +581,14 @@
   adapter()->NotifyGattServiceRemoved(service);
 }
 
-void BluetoothDeviceChromeOS::OnGetConnInfo(
-    const ConnectionInfoCallback& callback,
-    int16 rssi,
-    int16 transmit_power,
-    int16 max_transmit_power) {
+void BluetoothDeviceBlueZ::OnGetConnInfo(const ConnectionInfoCallback& callback,
+                                         int16 rssi,
+                                         int16 transmit_power,
+                                         int16 max_transmit_power) {
   callback.Run(ConnectionInfo(rssi, transmit_power, max_transmit_power));
 }
 
-void BluetoothDeviceChromeOS::OnGetConnInfoError(
+void BluetoothDeviceBlueZ::OnGetConnInfoError(
     const ConnectionInfoCallback& callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -602,28 +598,28 @@
   callback.Run(ConnectionInfo());
 }
 
-void BluetoothDeviceChromeOS::ConnectInternal(
+void BluetoothDeviceBlueZ::ConnectInternal(
     bool after_pairing,
     const base::Closure& callback,
     const ConnectErrorCallback& error_callback) {
   VLOG(1) << object_path_.value() << ": Connecting";
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Connect(
       object_path_,
-      base::Bind(&BluetoothDeviceChromeOS::OnConnect,
+      base::Bind(&BluetoothDeviceBlueZ::OnConnect,
                  weak_ptr_factory_.GetWeakPtr(), after_pairing, callback),
-      base::Bind(&BluetoothDeviceChromeOS::OnConnectError,
+      base::Bind(&BluetoothDeviceBlueZ::OnConnectError,
                  weak_ptr_factory_.GetWeakPtr(), after_pairing,
                  error_callback));
 }
 
-void BluetoothDeviceChromeOS::OnConnect(bool after_pairing,
-                                        const base::Closure& callback) {
+void BluetoothDeviceBlueZ::OnConnect(bool after_pairing,
+                                     const base::Closure& callback) {
   if (--num_connecting_calls_ == 0)
     adapter()->NotifyDeviceChanged(this);
 
   DCHECK(num_connecting_calls_ >= 0);
   VLOG(1) << object_path_.value() << ": Connected, " << num_connecting_calls_
-        << " still in progress";
+          << " still in progress";
 
   SetTrusted();
 
@@ -635,15 +631,14 @@
   callback.Run();
 }
 
-void BluetoothDeviceChromeOS::OnCreateGattConnection(
+void BluetoothDeviceBlueZ::OnCreateGattConnection(
     const GattConnectionCallback& callback) {
   scoped_ptr<device::BluetoothGattConnection> conn(
-      new BluetoothGattConnectionChromeOS(
-          adapter_, GetAddress(), object_path_));
+      new BluetoothGattConnectionBlueZ(adapter_, GetAddress(), object_path_));
   callback.Run(conn.Pass());
 }
 
-void BluetoothDeviceChromeOS::OnConnectError(
+void BluetoothDeviceBlueZ::OnConnectError(
     bool after_pairing,
     const ConnectErrorCallback& error_callback,
     const std::string& error_name,
@@ -652,8 +647,9 @@
     adapter()->NotifyDeviceChanged(this);
 
   DCHECK(num_connecting_calls_ >= 0);
-  LOG(WARNING) << object_path_.value() << ": Failed to connect device: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << object_path_.value()
+               << ": Failed to connect device: " << error_name << ": "
+               << error_message;
   VLOG(1) << object_path_.value() << ": " << num_connecting_calls_
           << " still in progress";
 
@@ -672,7 +668,7 @@
   error_callback.Run(error_code);
 }
 
-void BluetoothDeviceChromeOS::OnPairDuringConnect(
+void BluetoothDeviceBlueZ::OnPairDuringConnect(
     const base::Closure& callback,
     const ConnectErrorCallback& error_callback) {
   VLOG(1) << object_path_.value() << ": Paired";
@@ -682,7 +678,7 @@
   ConnectInternal(true, callback, error_callback);
 }
 
-void BluetoothDeviceChromeOS::OnPairDuringConnectError(
+void BluetoothDeviceBlueZ::OnPairDuringConnectError(
     const ConnectErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -690,8 +686,9 @@
     adapter()->NotifyDeviceChanged(this);
 
   DCHECK(num_connecting_calls_ >= 0);
-  LOG(WARNING) << object_path_.value() << ": Failed to pair device: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << object_path_.value()
+               << ": Failed to pair device: " << error_name << ": "
+               << error_message;
   VLOG(1) << object_path_.value() << ": " << num_connecting_calls_
           << " still in progress";
 
@@ -704,13 +701,13 @@
   error_callback.Run(error_code);
 }
 
-void BluetoothDeviceChromeOS::OnPair(const base::Closure& callback) {
+void BluetoothDeviceBlueZ::OnPair(const base::Closure& callback) {
   VLOG(1) << object_path_.value() << ": Paired";
   EndPairing();
   callback.Run();
 }
 
-void BluetoothDeviceChromeOS::OnPairError(
+void BluetoothDeviceBlueZ::OnPairError(
     const ConnectErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -723,14 +720,15 @@
   error_callback.Run(error_code);
 }
 
-void BluetoothDeviceChromeOS::OnCancelPairingError(
+void BluetoothDeviceBlueZ::OnCancelPairingError(
     const std::string& error_name,
     const std::string& error_message) {
-  LOG(WARNING) << object_path_.value() << ": Failed to cancel pairing: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << object_path_.value()
+               << ": Failed to cancel pairing: " << error_name << ": "
+               << error_message;
 }
 
-void BluetoothDeviceChromeOS::SetTrusted() {
+void BluetoothDeviceBlueZ::SetTrusted() {
   // Unconditionally send the property change, rather than checking the value
   // first; there's no harm in doing this and it solves any race conditions
   // with the property becoming true or false and this call happening before
@@ -738,36 +736,37 @@
   bluez::BluezDBusManager::Get()
       ->GetBluetoothDeviceClient()
       ->GetProperties(object_path_)
-      ->trusted.Set(true, base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted,
+      ->trusted.Set(true, base::Bind(&BluetoothDeviceBlueZ::OnSetTrusted,
                                      weak_ptr_factory_.GetWeakPtr()));
 }
 
-void BluetoothDeviceChromeOS::OnSetTrusted(bool success) {
+void BluetoothDeviceBlueZ::OnSetTrusted(bool success) {
   LOG_IF(WARNING, !success) << object_path_.value()
                             << ": Failed to set device as trusted";
 }
 
-void BluetoothDeviceChromeOS::OnDisconnect(const base::Closure& callback) {
+void BluetoothDeviceBlueZ::OnDisconnect(const base::Closure& callback) {
   VLOG(1) << object_path_.value() << ": Disconnected";
   callback.Run();
 }
 
-void BluetoothDeviceChromeOS::OnDisconnectError(
+void BluetoothDeviceBlueZ::OnDisconnectError(
     const ErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
-  LOG(WARNING) << object_path_.value() << ": Failed to disconnect device: "
-               << error_name << ": " << error_message;
+  LOG(WARNING) << object_path_.value()
+               << ": Failed to disconnect device: " << error_name << ": "
+               << error_message;
   error_callback.Run();
 }
 
-void BluetoothDeviceChromeOS::OnForgetError(
-    const ErrorCallback& error_callback,
-    const std::string& error_name,
-    const std::string& error_message) {
-  LOG(WARNING) << object_path_.value() << ": Failed to remove device: "
-               << error_name << ": " << error_message;
+void BluetoothDeviceBlueZ::OnForgetError(const ErrorCallback& error_callback,
+                                         const std::string& error_name,
+                                         const std::string& error_message) {
+  LOG(WARNING) << object_path_.value()
+               << ": Failed to remove device: " << error_name << ": "
+               << error_message;
   error_callback.Run();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_bluez.h
similarity index 88%
rename from device/bluetooth/bluetooth_device_chromeos.h
rename to device/bluetooth/bluetooth_device_bluez.h
index 544fdafe..8d93f308 100644
--- a/device/bluetooth/bluetooth_device_chromeos.h
+++ b/device/bluetooth/bluetooth_device_bluez.h
@@ -2,11 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_BLUEZ_H_
 
 #include <string>
 
+#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -21,19 +22,19 @@
 class BluetoothSocketThread;
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothAdapterChromeOS;
-class BluetoothPairingChromeOS;
+class BluetoothAdapterBlueZ;
+class BluetoothPairingBlueZ;
 
-// The BluetoothDeviceChromeOS class implements BluetoothDevice for the
+// The BluetoothDeviceBlueZ class implements BluetoothDevice for the
 // Chrome OS platform.
 //
 // This class is not thread-safe, but is only called from the UI thread.
 //
 // A socket thread is used to create sockets but posts all callbacks on the UI
 // thread.
-class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceChromeOS
+class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceBlueZ
     : public device::BluetoothDevice,
       public bluez::BluetoothGattServiceClient::Observer {
  public:
@@ -55,8 +56,7 @@
   bool ExpectingPinCode() const override;
   bool ExpectingPasskey() const override;
   bool ExpectingConfirmation() const override;
-  void GetConnectionInfo(
-      const ConnectionInfoCallback& callback) override;
+  void GetConnectionInfo(const ConnectionInfoCallback& callback) override;
   void Connect(device::BluetoothDevice::PairingDelegate* pairing_delegate,
                const base::Closure& callback,
                const ConnectErrorCallback& error_callback) override;
@@ -86,7 +86,7 @@
   // Creates a pairing object with the given delegate |pairing_delegate| and
   // establishes it as the pairing context for this device. All pairing-related
   // method calls will be forwarded to this object until it is released.
-  BluetoothPairingChromeOS* BeginPairing(
+  BluetoothPairingBlueZ* BeginPairing(
       BluetoothDevice::PairingDelegate* pairing_delegate);
 
   // Releases the current pairing object, any pairing-related method calls will
@@ -94,13 +94,13 @@
   void EndPairing();
 
   // Returns the current pairing object or NULL if no pairing is in progress.
-  BluetoothPairingChromeOS* GetPairing() const;
+  BluetoothPairingBlueZ* GetPairing() const;
 
   // Returns the object path of the device.
   const dbus::ObjectPath& object_path() const { return object_path_; }
 
   // Returns the adapter which owns this device instance.
-  BluetoothAdapterChromeOS* adapter() const;
+  BluetoothAdapterBlueZ* adapter() const;
 
  protected:
   // BluetoothDevice override
@@ -109,14 +109,14 @@
   void DisconnectGatt() override;
 
  private:
-  friend class BluetoothAdapterChromeOS;
+  friend class BluetoothAdapterBlueZ;
 
-  BluetoothDeviceChromeOS(
-      BluetoothAdapterChromeOS* adapter,
+  BluetoothDeviceBlueZ(
+      BluetoothAdapterBlueZ* adapter,
       const dbus::ObjectPath& object_path,
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
       scoped_refptr<device::BluetoothSocketThread> socket_thread);
-  ~BluetoothDeviceChromeOS() override;
+  ~BluetoothDeviceBlueZ() override;
 
   // bluez::BluetoothGattServiceClient::Observer overrides.
   void GattServiceAdded(const dbus::ObjectPath& object_path) override;
@@ -137,8 +137,7 @@
   void ConnectInternal(bool after_pairing,
                        const base::Closure& callback,
                        const ConnectErrorCallback& error_callback);
-  void OnConnect(bool after_pairing,
-                 const base::Closure& callback);
+  void OnConnect(bool after_pairing, const base::Closure& callback);
   void OnCreateGattConnection(const GattConnectionCallback& callback);
   void OnConnectError(bool after_pairing,
                       const ConnectErrorCallback& error_callback,
@@ -204,15 +203,15 @@
   // During pairing this is set to an object that we don't own, but on which
   // we can make method calls to request, display or confirm PIN Codes and
   // Passkeys. Generally it is the object that owns this one.
-  scoped_ptr<BluetoothPairingChromeOS> pairing_;
+  scoped_ptr<BluetoothPairingBlueZ> pairing_;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothDeviceChromeOS> weak_ptr_factory_;
+  base::WeakPtrFactory<BluetoothDeviceBlueZ> weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_discovery_session_outcome.h b/device/bluetooth/bluetooth_discovery_session_outcome.h
index 38cf3a1..9bc83a3 100644
--- a/device/bluetooth/bluetooth_discovery_session_outcome.h
+++ b/device/bluetooth/bluetooth_discovery_session_outcome.h
@@ -23,12 +23,12 @@
   ACTIVE_SESSION_NOT_IN_ADAPTER = 7,
   FAILED = 8,
 
-  // ChromeOS-specific failures:
-  CHROMEOS_DBUS_UNKNOWN_ADAPTER = 9,
-  CHROMEOS_DBUS_NO_RESPONSE = 10,
-  CHROMEOS_DBUS_IN_PROGRESS = 11,
-  CHROMEOS_DBUS_NOT_READY = 12,
-  CHROMEOS_DBUS_FAILED_MAYBE_UNSUPPORTED_TRANSPORT = 13,
+  // BlueZ-specific failures:
+  BLUEZ_DBUS_UNKNOWN_ADAPTER = 9,
+  BLUEZ_DBUS_NO_RESPONSE = 10,
+  BLUEZ_DBUS_IN_PROGRESS = 11,
+  BLUEZ_DBUS_NOT_READY = 12,
+  BLUEZ_DBUS_FAILED_MAYBE_UNSUPPORTED_TRANSPORT = 13,
   // NOTE: Add new outcomes immediately above this line. Make sure to update the
   // enum list in tools/metrics/histograms/histograms.xml accordingly.
   COUNT
diff --git a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc b/device/bluetooth/bluetooth_gatt_bluez_unittest.cc
similarity index 85%
rename from device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
rename to device/bluetooth/bluetooth_gatt_bluez_unittest.cc
index cf9e441f..777f5f1 100644
--- a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_gatt_bluez_unittest.cc
@@ -36,7 +36,7 @@
 using device::BluetoothUUID;
 using device::TestBluetoothAdapterObserver;
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -61,13 +61,12 @@
 
 }  // namespace
 
-class BluetoothGattChromeOSTest : public testing::Test {
+class BluetoothGattBlueZTest : public testing::Test {
  public:
-  BluetoothGattChromeOSTest()
+  BluetoothGattBlueZTest()
       : fake_bluetooth_gatt_service_client_(NULL),
         success_callback_count_(0),
-        error_callback_count_(0) {
-  }
+        error_callback_count_(0) {}
 
   void SetUp() override {
     scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
@@ -103,10 +102,8 @@
 
     GetAdapter();
 
-    adapter_->SetPowered(
-        true,
-        base::Bind(&base::DoNothing),
-        base::Bind(&base::DoNothing));
+    adapter_->SetPowered(true, base::Bind(&base::DoNothing),
+                         base::Bind(&base::DoNothing));
     ASSERT_TRUE(adapter_->IsPowered());
   }
 
@@ -118,9 +115,8 @@
   }
 
   void GetAdapter() {
-    device::BluetoothAdapterFactory::GetAdapter(
-        base::Bind(&BluetoothGattChromeOSTest::AdapterCallback,
-                   base::Unretained(this)));
+    device::BluetoothAdapterFactory::GetAdapter(base::Bind(
+        &BluetoothGattBlueZTest::AdapterCallback, base::Unretained(this)));
     ASSERT_TRUE(adapter_.get() != NULL);
     ASSERT_TRUE(adapter_->IsInitialized());
     ASSERT_TRUE(adapter_->IsPresent());
@@ -130,9 +126,7 @@
     adapter_ = adapter;
   }
 
-  void SuccessCallback() {
-    ++success_callback_count_;
-  }
+  void SuccessCallback() { ++success_callback_count_; }
 
   void ValueCallback(const std::vector<uint8>& value) {
     ++success_callback_count_;
@@ -155,9 +149,7 @@
     last_service_error_ = err;
   }
 
-  void ErrorCallback() {
-    ++error_callback_count_;
-  }
+  void ErrorCallback() { ++error_callback_count_; }
 
   void DBusErrorCallback(const std::string& error_name,
                          const std::string& error_message) {
@@ -193,7 +185,7 @@
   BluetoothGattService::GattErrorCode last_service_error_;
 };
 
-TEST_F(BluetoothGattChromeOSTest, GattConnection) {
+TEST_F(BluetoothGattBlueZTest, GattConnection) {
   fake_bluetooth_device_client_->CreateDevice(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
@@ -206,9 +198,9 @@
   ASSERT_EQ(0, error_callback_count_);
 
   device->CreateGattConnection(
-      base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback,
+      base::Bind(&BluetoothGattBlueZTest::GattConnectionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ConnectErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(1, success_callback_count_);
@@ -224,9 +216,9 @@
   EXPECT_FALSE(gatt_conn_->IsConnected());
 
   device->CreateGattConnection(
-      base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback,
+      base::Bind(&BluetoothGattBlueZTest::GattConnectionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ConnectErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(2, success_callback_count_);
@@ -235,11 +227,10 @@
   ASSERT_TRUE(gatt_conn_.get());
   EXPECT_TRUE(gatt_conn_->IsConnected());
 
-  device->Disconnect(
-      base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ErrorCallback,
-                 base::Unretained(this)));
+  device->Disconnect(base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
+                                base::Unretained(this)),
+                     base::Bind(&BluetoothGattBlueZTest::ErrorCallback,
+                                base::Unretained(this)));
 
   EXPECT_EQ(3, success_callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -247,9 +238,9 @@
   EXPECT_FALSE(gatt_conn_->IsConnected());
 
   device->CreateGattConnection(
-      base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback,
+      base::Bind(&BluetoothGattBlueZTest::GattConnectionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ConnectErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(4, success_callback_count_);
@@ -264,7 +255,7 @@
   EXPECT_FALSE(gatt_conn_->IsConnected());
 }
 
-TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) {
+TEST_F(BluetoothGattBlueZTest, GattServiceAddedAndRemoved) {
   // Create a fake LE device. We store the device pointer here because this is a
   // test. It's unsafe to do this in production as the device might get deleted.
   fake_bluetooth_device_client_->CreateDevice(
@@ -357,7 +348,7 @@
                       bluez::FakeBluetoothDeviceClient::kLowEnergyAddress));
 }
 
-TEST_F(BluetoothGattChromeOSTest, ServicesDiscovered) {
+TEST_F(BluetoothGattBlueZTest, ServicesDiscovered) {
   // Create a fake LE device. We store the device pointer here because this is a
   // test. It's unsafe to do this in production as the device might get deleted.
   fake_bluetooth_device_client_->CreateDevice(
@@ -388,7 +379,7 @@
             observer.last_device_address());
 }
 
-TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) {
+TEST_F(BluetoothGattBlueZTest, GattCharacteristicAddedAndRemoved) {
   fake_bluetooth_device_client_->CreateDevice(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
@@ -456,7 +447,7 @@
   EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
 }
 
-TEST_F(BluetoothGattChromeOSTest, GattDescriptorAddedAndRemoved) {
+TEST_F(BluetoothGattBlueZTest, GattDescriptorAddedAndRemoved) {
   fake_bluetooth_device_client_->CreateDevice(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
@@ -492,20 +483,20 @@
   EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
 
   BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetBodySensorLocationPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
+          .value());
   ASSERT_TRUE(characteristic);
   EXPECT_TRUE(characteristic->GetDescriptors().empty());
 
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateControlPointPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
+          .value());
   ASSERT_TRUE(characteristic);
   EXPECT_TRUE(characteristic->GetDescriptors().empty());
 
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateMeasurementPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
+          .value());
   ASSERT_TRUE(characteristic);
   EXPECT_EQ(1U, characteristic->GetDescriptors().size());
 
@@ -546,7 +537,7 @@
   EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id());
 }
 
-TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) {
+TEST_F(BluetoothGattBlueZTest, AdapterAddedAfterGattService) {
   // This unit test tests that all remote GATT objects are created for D-Bus
   // objects that were already exposed.
   adapter_ = NULL;
@@ -583,8 +574,8 @@
   EXPECT_EQ(3U, service->GetCharacteristics().size());
 
   BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetBodySensorLocationPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
+          .value());
   ASSERT_TRUE(characteristic);
   EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
                               kBodySensorLocationUUID),
@@ -593,8 +584,8 @@
   EXPECT_TRUE(characteristic->GetDescriptors().empty());
 
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateControlPointPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
+          .value());
   ASSERT_TRUE(characteristic);
   EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
                               kHeartRateControlPointUUID),
@@ -603,8 +594,8 @@
   EXPECT_TRUE(characteristic->GetDescriptors().empty());
 
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateMeasurementPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
+          .value());
   ASSERT_TRUE(characteristic);
   EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
                               kHeartRateMeasurementUUID),
@@ -619,7 +610,7 @@
   EXPECT_FALSE(descriptor->IsLocal());
 }
 
-TEST_F(BluetoothGattChromeOSTest, GattCharacteristicValue) {
+TEST_F(BluetoothGattBlueZTest, GattCharacteristicValue) {
   fake_bluetooth_device_client_->CreateDevice(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
@@ -648,20 +639,20 @@
 
   std::vector<uint8> write_value;
   write_value.push_back(0x01);
-  BluetoothGattCharacteristic* characteristic =
-      service->GetCharacteristic(fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateMeasurementPath().value());
+  BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
+          .value());
   ASSERT_TRUE(characteristic);
   EXPECT_FALSE(characteristic->IsNotifying());
-  EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
-                GetHeartRateMeasurementPath().value(),
-            characteristic->GetIdentifier());
+  EXPECT_EQ(
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
+          .value(),
+      characteristic->GetIdentifier());
   EXPECT_EQ(kHeartRateMeasurementUUID, characteristic->GetUUID());
   characteristic->WriteRemoteCharacteristic(
-      write_value,
-      base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      write_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
+                              base::Unretained(this)),
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
   EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
@@ -672,18 +663,18 @@
   EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
 
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetBodySensorLocationPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
+          .value());
   ASSERT_TRUE(characteristic);
-  EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
-                GetBodySensorLocationPath().value(),
-            characteristic->GetIdentifier());
+  EXPECT_EQ(
+      fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
+          .value(),
+      characteristic->GetIdentifier());
   EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
   characteristic->WriteRemoteCharacteristic(
-      write_value,
-      base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      write_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
+                              base::Unretained(this)),
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
   EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
@@ -698,18 +689,18 @@
   // in a CharacteristicValueChanged event, thus no such event should be
   // received.
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateControlPointPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
+          .value());
   ASSERT_TRUE(characteristic);
-  EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
-                GetHeartRateControlPointPath().value(),
-            characteristic->GetIdentifier());
+  EXPECT_EQ(
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
+          .value(),
+      characteristic->GetIdentifier());
   EXPECT_EQ(kHeartRateControlPointUUID, characteristic->GetUUID());
   characteristic->WriteRemoteCharacteristic(
-      write_value,
-      base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      write_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
+                              base::Unretained(this)),
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
   EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
@@ -724,10 +715,9 @@
   invalid_write_length.push_back(0x01);
   invalid_write_length.push_back(0x00);
   characteristic->WriteRemoteCharacteristic(
-      invalid_write_length,
-      base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      invalid_write_length, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
+                                       base::Unretained(this)),
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(1, success_callback_count_);
   EXPECT_EQ(3, error_callback_count_);
@@ -738,10 +728,9 @@
   std::vector<uint8> invalid_write_value;
   invalid_write_value.push_back(0x02);
   characteristic->WriteRemoteCharacteristic(
-      invalid_write_value,
-      base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      invalid_write_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
+                                      base::Unretained(this)),
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(1, success_callback_count_);
   EXPECT_EQ(4, error_callback_count_);
@@ -751,17 +740,18 @@
   // Issue a read request. A successful read results in a
   // CharacteristicValueChanged notification.
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetBodySensorLocationPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
+          .value());
   ASSERT_TRUE(characteristic);
-  EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
-                GetBodySensorLocationPath().value(),
-            characteristic->GetIdentifier());
+  EXPECT_EQ(
+      fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
+          .value(),
+      characteristic->GetIdentifier());
   EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
   characteristic->ReadRemoteCharacteristic(
-      base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
+      base::Bind(&BluetoothGattBlueZTest::ValueCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(2, success_callback_count_);
   EXPECT_EQ(4, error_callback_count_);
@@ -780,9 +770,9 @@
       characteristic->GetIdentifier());
   EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
   characteristic->ReadRemoteCharacteristic(
-      base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
+      base::Bind(&BluetoothGattBlueZTest::ValueCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
 
   // Callback counts shouldn't change, this one will be delayed until after
@@ -793,9 +783,9 @@
 
   // Next read should error because IN_PROGRESS
   characteristic->ReadRemoteCharacteristic(
-      base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
+      base::Bind(&BluetoothGattBlueZTest::ValueCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(5, error_callback_count_);
   EXPECT_EQ(BluetoothGattService::GATT_ERROR_IN_PROGRESS, last_service_error_);
@@ -809,9 +799,9 @@
   // Test unauthorized actions.
   fake_bluetooth_gatt_characteristic_client_->SetAuthorized(false);
   characteristic->ReadRemoteCharacteristic(
-      base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
+      base::Bind(&BluetoothGattBlueZTest::ValueCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(3, success_callback_count_);
   EXPECT_EQ(6, error_callback_count_);
@@ -823,9 +813,9 @@
   // Test unauthenticated / needs login.
   fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(false);
   characteristic->ReadRemoteCharacteristic(
-      base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
+      base::Bind(&BluetoothGattBlueZTest::ValueCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(3, success_callback_count_);
   EXPECT_EQ(7, error_callback_count_);
@@ -834,7 +824,7 @@
   fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(true);
 }
 
-TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) {
+TEST_F(BluetoothGattBlueZTest, GattCharacteristicProperties) {
   fake_bluetooth_device_client_->CreateDevice(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
@@ -857,26 +847,26 @@
   // Run the message loop so that the characteristics appear.
   base::MessageLoop::current()->Run();
 
-  BluetoothGattCharacteristic *characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetBodySensorLocationPath().value());
+  BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
+      fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
+          .value());
   EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_READ,
             characteristic->GetProperties());
 
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateControlPointPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
+          .value());
   EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_WRITE,
             characteristic->GetProperties());
 
   characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateMeasurementPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
+          .value());
   EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_NOTIFY,
             characteristic->GetProperties());
 }
 
-TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
+TEST_F(BluetoothGattBlueZTest, GattDescriptorValue) {
   fake_bluetooth_device_client_->CreateDevice(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
@@ -907,8 +897,8 @@
 
   // Only the Heart Rate Measurement characteristic has a descriptor.
   BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
-      fake_bluetooth_gatt_characteristic_client_->
-          GetHeartRateMeasurementPath().value());
+      fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
+          .value());
   ASSERT_TRUE(characteristic);
   EXPECT_EQ(1U, characteristic->GetDescriptors().size());
   EXPECT_FALSE(characteristic->IsNotifying());
@@ -931,9 +921,9 @@
   // Read value. GattDescriptorValueChanged event will be sent after a
   // successful read.
   descriptor->ReadRemoteDescriptor(
-      base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
+      base::Bind(&BluetoothGattBlueZTest::ValueCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(1, success_callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -945,10 +935,9 @@
   // Write value. Writes to this descriptor will fail.
   desc_value[0] = 0x03;
   descriptor->WriteRemoteDescriptor(
-      desc_value,
-      base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      desc_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
+                             base::Unretained(this)),
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(1, success_callback_count_);
   EXPECT_EQ(1, error_callback_count_);
@@ -961,9 +950,9 @@
 
   // Read value. The value should remain unchanged.
   descriptor->ReadRemoteDescriptor(
-      base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
+      base::Bind(&BluetoothGattBlueZTest::ValueCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(2, success_callback_count_);
   EXPECT_EQ(1, error_callback_count_);
@@ -975,9 +964,9 @@
   // Start notifications on the descriptor's characteristic. The descriptor
   // value should change.
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   base::MessageLoop::current()->Run();
   EXPECT_EQ(3, success_callback_count_);
@@ -987,9 +976,9 @@
 
   // Read the new descriptor value. We should receive a value updated event.
   descriptor->ReadRemoteDescriptor(
-      base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
+      base::Bind(&BluetoothGattBlueZTest::ValueCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(4, success_callback_count_);
   EXPECT_EQ(1, error_callback_count_);
@@ -999,7 +988,7 @@
   EXPECT_EQ(2, observer.gatt_descriptor_value_changed_count());
 }
 
-TEST_F(BluetoothGattChromeOSTest, NotifySessions) {
+TEST_F(BluetoothGattBlueZTest, NotifySessions) {
   fake_bluetooth_device_client_->CreateDevice(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
@@ -1032,9 +1021,9 @@
 
   // Request to start notifications.
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
 
   // The operation still hasn't completed but we should have received the first
@@ -1046,14 +1035,14 @@
 
   // Send a two more requests, which should get queued.
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(0, success_callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1078,7 +1067,7 @@
   // characteristic should still be notifying.
   BluetoothGattNotifySession* session = update_sessions_[0];
   EXPECT_TRUE(session->IsActive());
-  session->Stop(base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
+  session->Stop(base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
                            base::Unretained(this)));
   EXPECT_EQ(4, success_callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1104,9 +1093,9 @@
 
   // Enable notifications again.
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(0, success_callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1130,9 +1119,9 @@
 
   // Request another session. This should return immediately.
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(2, success_callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1148,7 +1137,7 @@
   EXPECT_FALSE(update_sessions_[1]->IsActive());
 }
 
-TEST_F(BluetoothGattChromeOSTest, NotifySessionsMadeInactive) {
+TEST_F(BluetoothGattBlueZTest, NotifySessionsMadeInactive) {
   fake_bluetooth_device_client_->CreateDevice(
       dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
       dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
@@ -1181,24 +1170,24 @@
 
   // Send several requests to start notifications.
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
 
   // The operation still hasn't completed but we should have received the first
@@ -1226,9 +1215,9 @@
   // marked as inactive.
   fake_bluetooth_gatt_characteristic_client_->StopNotify(
       fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath(),
-      base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
+      base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::DBusErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::DBusErrorCallback,
                  base::Unretained(this)));
   EXPECT_EQ(5, success_callback_count_);
   EXPECT_EQ(0, error_callback_count_);
@@ -1244,9 +1233,9 @@
   success_callback_count_ = 0;
   observer.Reset();
   characteristic->StartNotifySession(
-      base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
+      base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
+      base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
                  base::Unretained(this)));
 
   EXPECT_EQ(0, success_callback_count_);
@@ -1265,4 +1254,4 @@
   EXPECT_TRUE(update_sessions_[0]->IsActive());
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_gatt_characteristic_unittest.cc b/device/bluetooth/bluetooth_gatt_characteristic_unittest.cc
index 095d2b3b..cf2fdddb 100644
--- a/device/bluetooth/bluetooth_gatt_characteristic_unittest.cc
+++ b/device/bluetooth/bluetooth_gatt_characteristic_unittest.cc
@@ -561,4 +561,75 @@
 }
 #endif  // defined(OS_ANDROID)
 
+#if defined(OS_ANDROID)
+// Tests StartNotifySession success.
+TEST_F(BluetoothGattCharacteristicTest, StartNotifySession) {
+  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate());
+
+  characteristic1_->StartNotifySession(GetNotifyCallback(),
+                                       GetGattErrorCallback());
+  EXPECT_EQ(1, gatt_notify_characteristic_attempts_);
+  EXPECT_EQ(0, callback_count_);
+  SimulateGattNotifySessionStarted(characteristic1_);
+  EXPECT_EQ(1, callback_count_);
+  EXPECT_EQ(0, error_callback_count_);
+  ASSERT_EQ(1u, notify_sessions_.size());
+  ASSERT_TRUE(notify_sessions_[0]);
+  EXPECT_EQ(characteristic1_->GetIdentifier(),
+            notify_sessions_[0]->GetCharacteristicIdentifier());
+  EXPECT_TRUE(notify_sessions_[0]->IsActive());
+}
+#endif  // defined(OS_ANDROID)
+
+#if defined(OS_ANDROID)
+// Tests StartNotifySession synchronous failure.
+TEST_F(BluetoothGattCharacteristicTest, StartNotifySession_SynchronousError) {
+  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate());
+
+  SimulateGattCharacteristicSetNotifyWillFailSynchronouslyOnce(
+      characteristic1_);
+  characteristic1_->StartNotifySession(GetNotifyCallback(),
+                                       GetGattErrorCallback());
+  EXPECT_EQ(0, error_callback_count_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(0, gatt_notify_characteristic_attempts_);
+  EXPECT_EQ(0, callback_count_);
+  EXPECT_EQ(1, error_callback_count_);
+  ASSERT_EQ(0u, notify_sessions_.size());
+}
+#endif  // defined(OS_ANDROID)
+
+#if defined(OS_ANDROID)
+// Tests multiple StartNotifySession success.
+TEST_F(BluetoothGattCharacteristicTest, StartNotifySession_Multiple) {
+  ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate());
+
+  characteristic1_->StartNotifySession(GetNotifyCallback(),
+                                       GetGattErrorCallback());
+  characteristic1_->StartNotifySession(GetNotifyCallback(),
+                                       GetGattErrorCallback());
+#if defined(OS_ANDROID)
+  // TODO(crbug.com/551634): Decide when implementing IsNotifying if Android
+  // should trust the notification request always worked, or if we should always
+  // redundantly set the value to the OS.
+  EXPECT_EQ(2, gatt_notify_characteristic_attempts_);
+#else
+  EXPECT_EQ(1, gatt_notify_characteristic_attempts_);
+#endif
+  EXPECT_EQ(0, callback_count_);
+  SimulateGattNotifySessionStarted(characteristic1_);
+  EXPECT_EQ(2, callback_count_);
+  EXPECT_EQ(0, error_callback_count_);
+  ASSERT_EQ(2u, notify_sessions_.size());
+  ASSERT_TRUE(notify_sessions_[0]);
+  ASSERT_TRUE(notify_sessions_[1]);
+  EXPECT_EQ(characteristic1_->GetIdentifier(),
+            notify_sessions_[0]->GetCharacteristicIdentifier());
+  EXPECT_EQ(characteristic1_->GetIdentifier(),
+            notify_sessions_[1]->GetCharacteristicIdentifier());
+  EXPECT_TRUE(notify_sessions_[0]->IsActive());
+  EXPECT_TRUE(notify_sessions_[1]->IsActive());
+}
+#endif  // defined(OS_ANDROID)
+
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_gatt_connection_chromeos.cc b/device/bluetooth/bluetooth_gatt_connection_bluez.cc
similarity index 86%
rename from device/bluetooth/bluetooth_gatt_connection_chromeos.cc
rename to device/bluetooth/bluetooth_gatt_connection_bluez.cc
index 57aaa4d3..98b6a469 100644
--- a/device/bluetooth/bluetooth_gatt_connection_chromeos.cc
+++ b/device/bluetooth/bluetooth_gatt_connection_bluez.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_gatt_connection_chromeos.h"
+#include "device/bluetooth/bluetooth_gatt_connection_bluez.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -10,9 +10,9 @@
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
-namespace chromeos {
+namespace bluez {
 
-BluetoothGattConnectionChromeOS::BluetoothGattConnectionChromeOS(
+BluetoothGattConnectionBlueZ::BluetoothGattConnectionBlueZ(
     scoped_refptr<device::BluetoothAdapter> adapter,
     const std::string& device_address,
     const dbus::ObjectPath& object_path)
@@ -26,13 +26,13 @@
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
 }
 
-BluetoothGattConnectionChromeOS::~BluetoothGattConnectionChromeOS() {
+BluetoothGattConnectionBlueZ::~BluetoothGattConnectionBlueZ() {
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(
       this);
   Disconnect();
 }
 
-bool BluetoothGattConnectionChromeOS::IsConnected() {
+bool BluetoothGattConnectionBlueZ::IsConnected() {
   // Lazily determine the activity state of the connection. If already
   // marked as inactive, then return false. Otherwise, explicitly mark
   // |connected_| as false if the device is removed or disconnected. We do this,
@@ -50,7 +50,7 @@
   return connected_;
 }
 
-void BluetoothGattConnectionChromeOS::Disconnect() {
+void BluetoothGattConnectionBlueZ::Disconnect() {
   if (!connected_) {
     VLOG(1) << "Connection already inactive.";
     return;
@@ -66,7 +66,7 @@
   connected_ = false;
 }
 
-void BluetoothGattConnectionChromeOS::DeviceRemoved(
+void BluetoothGattConnectionBlueZ::DeviceRemoved(
     const dbus::ObjectPath& object_path) {
   if (object_path != object_path_)
     return;
@@ -74,7 +74,7 @@
   connected_ = false;
 }
 
-void BluetoothGattConnectionChromeOS::DevicePropertyChanged(
+void BluetoothGattConnectionBlueZ::DevicePropertyChanged(
     const dbus::ObjectPath& object_path,
     const std::string& property_name) {
   if (object_path != object_path_)
@@ -102,4 +102,4 @@
     device_address_ = properties->address.value();
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_gatt_connection_chromeos.h b/device/bluetooth/bluetooth_gatt_connection_bluez.h
similarity index 71%
rename from device/bluetooth/bluetooth_gatt_connection_chromeos.h
rename to device/bluetooth/bluetooth_gatt_connection_bluez.h
index 6e40283b..e9bee29 100644
--- a/device/bluetooth/bluetooth_gatt_connection_chromeos.h
+++ b/device/bluetooth/bluetooth_gatt_connection_bluez.h
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_GATT_CONNECTION_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_GATT_CONNECTION_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_GATT_CONNECTION_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_GATT_CONNECTION_BLUEZ_H_
 
 #include <string>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_gatt_connection.h"
@@ -19,19 +20,19 @@
 
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
-// BluetoothGattConnectionChromeOS implements BluetoothGattConnection for the
+// BluetoothGattConnectionBlueZ implements BluetoothGattConnection for the
 // Chrome OS platform.
-class BluetoothGattConnectionChromeOS
+class BluetoothGattConnectionBlueZ
     : public device::BluetoothGattConnection,
       public bluez::BluetoothDeviceClient::Observer {
  public:
-  explicit BluetoothGattConnectionChromeOS(
+  explicit BluetoothGattConnectionBlueZ(
       scoped_refptr<device::BluetoothAdapter> adapter,
       const std::string& device_address,
       const dbus::ObjectPath& object_path);
-  ~BluetoothGattConnectionChromeOS() override;
+  ~BluetoothGattConnectionBlueZ() override;
 
   // BluetoothGattConnection overrides.
   bool IsConnected() override;
@@ -50,9 +51,9 @@
   // events.
   dbus::ObjectPath object_path_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattConnectionChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattConnectionBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_GATT_CONNECTION_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_GATT_CONNECTION_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_gatt_notify_session_android.cc b/device/bluetooth/bluetooth_gatt_notify_session_android.cc
new file mode 100644
index 0000000..9f6e5539
--- /dev/null
+++ b/device/bluetooth/bluetooth_gatt_notify_session_android.cc
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/bluetooth_gatt_notify_session_android.h"
+
+#include "base/logging.h"
+
+namespace device {
+
+BluetoothGattNotifySessionAndroid::BluetoothGattNotifySessionAndroid(
+    const std::string& characteristic_identifier)
+    : characteristic_id_(characteristic_identifier) {}
+
+BluetoothGattNotifySessionAndroid::~BluetoothGattNotifySessionAndroid() {}
+
+std::string BluetoothGattNotifySessionAndroid::GetCharacteristicIdentifier()
+    const {
+  return characteristic_id_;
+}
+
+bool BluetoothGattNotifySessionAndroid::IsActive() {
+  return true;
+}
+
+void BluetoothGattNotifySessionAndroid::Stop(const base::Closure& callback) {
+  NOTIMPLEMENTED();
+}
+
+}  // namespace device
diff --git a/device/bluetooth/bluetooth_gatt_notify_session_android.h b/device/bluetooth/bluetooth_gatt_notify_session_android.h
new file mode 100644
index 0000000..8413f87
--- /dev/null
+++ b/device/bluetooth/bluetooth_gatt_notify_session_android.h
@@ -0,0 +1,45 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_ANDROID_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_ANDROID_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "device/bluetooth/bluetooth_gatt_notify_session.h"
+
+namespace device {
+
+class BluetoothAdapter;
+class BluetoothRemoteGattCharacteristicAndroid;
+
+// BluetoothGattNotifySessionAndroid implements
+// BluetoothGattNotifySession for the Android platform.
+//
+// TODO(crbug.com/551634): Detect destroyed Characteristic or parents objects.
+// TODO(crbug.com/551634): Implement Stop.
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattNotifySessionAndroid
+    : public device::BluetoothGattNotifySession {
+ public:
+  explicit BluetoothGattNotifySessionAndroid(
+      const std::string& characteristic_identifier);
+  ~BluetoothGattNotifySessionAndroid() override;
+
+  // BluetoothGattNotifySession overrides.
+  std::string GetCharacteristicIdentifier() const override;
+  bool IsActive() override;
+  void Stop(const base::Closure& callback) override;
+
+ private:
+  // Identifier of the associated characteristic.
+  std::string characteristic_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattNotifySessionAndroid);
+};
+
+}  // namespace device
+
+#endif  //  DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_ANDROID_H_
diff --git a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc b/device/bluetooth/bluetooth_gatt_notify_session_bluez.cc
similarity index 82%
rename from device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc
rename to device/bluetooth/bluetooth_gatt_notify_session_bluez.cc
index 02f7ed8b..7e1cfed4 100644
--- a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc
+++ b/device/bluetooth/bluetooth_gatt_notify_session_bluez.cc
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_gatt_notify_session_chromeos.h"
+#include "device/bluetooth/bluetooth_gatt_notify_session_bluez.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_gatt_service.h"
-#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
-namespace chromeos {
+namespace bluez {
 
-BluetoothGattNotifySessionChromeOS::BluetoothGattNotifySessionChromeOS(
+BluetoothGattNotifySessionBlueZ::BluetoothGattNotifySessionBlueZ(
     scoped_refptr<device::BluetoothAdapter> adapter,
     const std::string& device_address,
     const std::string& service_identifier,
@@ -37,19 +37,19 @@
       ->AddObserver(this);
 }
 
-BluetoothGattNotifySessionChromeOS::~BluetoothGattNotifySessionChromeOS() {
+BluetoothGattNotifySessionBlueZ::~BluetoothGattNotifySessionBlueZ() {
   bluez::BluezDBusManager::Get()
       ->GetBluetoothGattCharacteristicClient()
       ->RemoveObserver(this);
   Stop(base::Bind(&base::DoNothing));
 }
 
-std::string BluetoothGattNotifySessionChromeOS::GetCharacteristicIdentifier()
+std::string BluetoothGattNotifySessionBlueZ::GetCharacteristicIdentifier()
     const {
   return characteristic_id_;
 }
 
-bool BluetoothGattNotifySessionChromeOS::IsActive() {
+bool BluetoothGattNotifySessionBlueZ::IsActive() {
   // Determine if the session is active. If |active_| is false, then it's
   // been explicitly marked, so return false.
   if (!active_)
@@ -73,7 +73,7 @@
   return active_;
 }
 
-void BluetoothGattNotifySessionChromeOS::Stop(const base::Closure& callback) {
+void BluetoothGattNotifySessionBlueZ::Stop(const base::Closure& callback) {
   if (!active_) {
     VLOG(1) << "Notify session already inactive.";
     callback.Run();
@@ -91,8 +91,8 @@
   if (!service)
     return;
 
-  BluetoothRemoteGattCharacteristicChromeOS* chrc =
-      static_cast<BluetoothRemoteGattCharacteristicChromeOS*>(
+  BluetoothRemoteGattCharacteristicBlueZ* chrc =
+      static_cast<BluetoothRemoteGattCharacteristicBlueZ*>(
           service->GetCharacteristic(characteristic_id_));
   if (!chrc)
     return;
@@ -100,7 +100,7 @@
   chrc->RemoveNotifySession(callback);
 }
 
-void BluetoothGattNotifySessionChromeOS::GattCharacteristicRemoved(
+void BluetoothGattNotifySessionBlueZ::GattCharacteristicRemoved(
     const dbus::ObjectPath& object_path) {
   if (object_path != object_path_)
     return;
@@ -108,7 +108,7 @@
   active_ = false;
 }
 
-void BluetoothGattNotifySessionChromeOS::GattCharacteristicPropertyChanged(
+void BluetoothGattNotifySessionBlueZ::GattCharacteristicPropertyChanged(
     const dbus::ObjectPath& object_path,
     const std::string& property_name) {
   if (object_path != object_path_)
@@ -131,4 +131,4 @@
     active_ = false;
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h b/device/bluetooth/bluetooth_gatt_notify_session_bluez.h
similarity index 75%
rename from device/bluetooth/bluetooth_gatt_notify_session_chromeos.h
rename to device/bluetooth/bluetooth_gatt_notify_session_bluez.h
index ef6e8da4..4c99d47 100644
--- a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h
+++ b/device/bluetooth/bluetooth_gatt_notify_session_bluez.h
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_BLUEZ_H_
 
 #include <string>
 
 #include "base/callback.h"
+#include "base/macros.h"
 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
 
@@ -17,17 +18,17 @@
 
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothRemoteGattCharacteristicChromeOS;
+class BluetoothRemoteGattCharacteristicBlueZ;
 
-// BluetoothGattNotifySessionChromeOS implements
+// BluetoothGattNotifySessionBlueZ implements
 // BluetoothGattNotifySession for the Chrome OS platform.
-class BluetoothGattNotifySessionChromeOS
+class BluetoothGattNotifySessionBlueZ
     : public device::BluetoothGattNotifySession,
       public bluez::BluetoothGattCharacteristicClient::Observer {
  public:
-  ~BluetoothGattNotifySessionChromeOS() override;
+  ~BluetoothGattNotifySessionBlueZ() override;
 
   // BluetoothGattNotifySession overrides.
   std::string GetCharacteristicIdentifier() const override;
@@ -35,9 +36,9 @@
   void Stop(const base::Closure& callback) override;
 
  private:
-  friend class BluetoothRemoteGattCharacteristicChromeOS;
+  friend class BluetoothRemoteGattCharacteristicBlueZ;
 
-  explicit BluetoothGattNotifySessionChromeOS(
+  explicit BluetoothGattNotifySessionBlueZ(
       scoped_refptr<device::BluetoothAdapter> adapter,
       const std::string& device_address,
       const std::string& service_identifier,
@@ -69,9 +70,9 @@
   // observer events.
   dbus::ObjectPath object_path_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattNotifySessionChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattNotifySessionBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  //  DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_CHROMEOS_H_
+#endif  //  DEVICE_BLUETOOTH_BLUETOOTH_GATT_NOTIFY_SESSION_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_pairing_chromeos.cc b/device/bluetooth/bluetooth_pairing_bluez.cc
similarity index 81%
rename from device/bluetooth/bluetooth_pairing_chromeos.cc
rename to device/bluetooth/bluetooth_pairing_bluez.cc
index 4541fb38..a798694 100644
--- a/device/bluetooth/bluetooth_pairing_chromeos.cc
+++ b/device/bluetooth/bluetooth_pairing_bluez.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_pairing_chromeos.h"
+#include "device/bluetooth/bluetooth_pairing_bluez.h"
 
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
 #include "device/bluetooth/bluetooth_device.h"
-#include "device/bluetooth/bluetooth_device_chromeos.h"
+#include "device/bluetooth/bluetooth_device_bluez.h"
 
 using device::BluetoothDevice;
 
@@ -32,21 +32,19 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
-BluetoothPairingChromeOS::BluetoothPairingChromeOS(
-    BluetoothDeviceChromeOS* device,
+BluetoothPairingBlueZ::BluetoothPairingBlueZ(
+    BluetoothDeviceBlueZ* device,
     BluetoothDevice::PairingDelegate* pairing_delegate)
     : device_(device),
       pairing_delegate_(pairing_delegate),
       pairing_delegate_used_(false) {
-  VLOG(1) << "Created BluetoothPairingChromeOS for "
-          << device_->GetAddress();
+  VLOG(1) << "Created BluetoothPairingBlueZ for " << device_->GetAddress();
 }
 
-BluetoothPairingChromeOS::~BluetoothPairingChromeOS() {
-  VLOG(1) << "Destroying BluetoothPairingChromeOS for "
-          << device_->GetAddress();
+BluetoothPairingBlueZ::~BluetoothPairingBlueZ() {
+  VLOG(1) << "Destroying BluetoothPairingBlueZ for " << device_->GetAddress();
 
   if (!pairing_delegate_used_) {
     UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
@@ -72,7 +70,7 @@
   pairing_delegate_ = NULL;
 }
 
-void BluetoothPairingChromeOS::RequestPinCode(
+void BluetoothPairingBlueZ::RequestPinCode(
     const bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback&
         callback) {
   UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
@@ -85,11 +83,11 @@
   pairing_delegate_->RequestPinCode(device_);
 }
 
-bool BluetoothPairingChromeOS::ExpectingPinCode() const {
+bool BluetoothPairingBlueZ::ExpectingPinCode() const {
   return !pincode_callback_.is_null();
 }
 
-void BluetoothPairingChromeOS::SetPinCode(const std::string& pincode) {
+void BluetoothPairingBlueZ::SetPinCode(const std::string& pincode) {
   if (pincode_callback_.is_null())
     return;
 
@@ -104,7 +102,7 @@
     device_->EndPairing();
 }
 
-void BluetoothPairingChromeOS::DisplayPinCode(const std::string& pincode) {
+void BluetoothPairingBlueZ::DisplayPinCode(const std::string& pincode) {
   UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
                             UMA_PAIRING_METHOD_DISPLAY_PINCODE,
                             UMA_PAIRING_METHOD_COUNT);
@@ -120,7 +118,7 @@
     device_->EndPairing();
 }
 
-void BluetoothPairingChromeOS::RequestPasskey(
+void BluetoothPairingBlueZ::RequestPasskey(
     const bluez::BluetoothAgentServiceProvider::Delegate::PasskeyCallback&
         callback) {
   UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
@@ -133,11 +131,11 @@
   pairing_delegate_->RequestPasskey(device_);
 }
 
-bool BluetoothPairingChromeOS::ExpectingPasskey() const {
+bool BluetoothPairingBlueZ::ExpectingPasskey() const {
   return !passkey_callback_.is_null();
 }
 
-void BluetoothPairingChromeOS::SetPasskey(uint32 passkey) {
+void BluetoothPairingBlueZ::SetPasskey(uint32 passkey) {
   if (passkey_callback_.is_null())
     return;
 
@@ -152,7 +150,7 @@
     device_->EndPairing();
 }
 
-void BluetoothPairingChromeOS::DisplayPasskey(uint32 passkey) {
+void BluetoothPairingBlueZ::DisplayPasskey(uint32 passkey) {
   UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
                             UMA_PAIRING_METHOD_DISPLAY_PASSKEY,
                             UMA_PAIRING_METHOD_COUNT);
@@ -162,7 +160,7 @@
   pairing_delegate_->DisplayPasskey(device_, passkey);
 }
 
-void BluetoothPairingChromeOS::KeysEntered(uint16 entered) {
+void BluetoothPairingBlueZ::KeysEntered(uint16 entered) {
   pairing_delegate_used_ = true;
   pairing_delegate_->KeysEntered(device_, entered);
 
@@ -173,7 +171,7 @@
     device_->EndPairing();
 }
 
-void BluetoothPairingChromeOS::RequestConfirmation(
+void BluetoothPairingBlueZ::RequestConfirmation(
     uint32 passkey,
     const bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
         callback) {
@@ -187,11 +185,10 @@
   pairing_delegate_->ConfirmPasskey(device_, passkey);
 }
 
-void BluetoothPairingChromeOS::RequestAuthorization(
+void BluetoothPairingBlueZ::RequestAuthorization(
     const bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback&
         callback) {
-  UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
-                            UMA_PAIRING_METHOD_NONE,
+  UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", UMA_PAIRING_METHOD_NONE,
                             UMA_PAIRING_METHOD_COUNT);
 
   ResetCallbacks();
@@ -200,11 +197,11 @@
   pairing_delegate_->AuthorizePairing(device_);
 }
 
-bool BluetoothPairingChromeOS::ExpectingConfirmation() const {
+bool BluetoothPairingBlueZ::ExpectingConfirmation() const {
   return !confirmation_callback_.is_null();
 }
 
-void BluetoothPairingChromeOS::ConfirmPairing() {
+void BluetoothPairingBlueZ::ConfirmPairing() {
   if (confirmation_callback_.is_null())
     return;
 
@@ -219,28 +216,28 @@
     device_->EndPairing();
 }
 
-bool BluetoothPairingChromeOS::RejectPairing() {
+bool BluetoothPairingBlueZ::RejectPairing() {
   return RunPairingCallbacks(
       bluez::BluetoothAgentServiceProvider::Delegate::REJECTED);
 }
 
-bool BluetoothPairingChromeOS::CancelPairing() {
+bool BluetoothPairingBlueZ::CancelPairing() {
   return RunPairingCallbacks(
       bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED);
 }
 
-BluetoothDevice::PairingDelegate*
-BluetoothPairingChromeOS::GetPairingDelegate() const {
+BluetoothDevice::PairingDelegate* BluetoothPairingBlueZ::GetPairingDelegate()
+    const {
   return pairing_delegate_;
 }
 
-void BluetoothPairingChromeOS::ResetCallbacks() {
+void BluetoothPairingBlueZ::ResetCallbacks() {
   pincode_callback_.Reset();
   passkey_callback_.Reset();
   confirmation_callback_.Reset();
 }
 
-bool BluetoothPairingChromeOS::RunPairingCallbacks(
+bool BluetoothPairingBlueZ::RunPairingCallbacks(
     bluez::BluetoothAgentServiceProvider::Delegate::Status status) {
   pairing_delegate_used_ = true;
 
@@ -272,4 +269,4 @@
   return callback_run;
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_pairing_chromeos.h b/device/bluetooth/bluetooth_pairing_bluez.h
similarity index 86%
rename from device/bluetooth/bluetooth_pairing_chromeos.h
rename to device/bluetooth/bluetooth_pairing_bluez.h
index 0a4ddb6..2851faf 100644
--- a/device/bluetooth/bluetooth_pairing_chromeos.h
+++ b/device/bluetooth/bluetooth_pairing_bluez.h
@@ -2,26 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_BLUEZ_H_
 
+#include "base/macros.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothDeviceChromeOS;
+class BluetoothDeviceBlueZ;
 
-// The BluetoothPairingChromeOS class encapsulates the logic for an individual
-// device pairing, acting as a bridge between BluetoothAdapterChromeOS which
+// The BluetoothPairingBlueZ class encapsulates the logic for an individual
+// device pairing, acting as a bridge between BluetoothAdapterBlueZ which
 // communicates with the underlying Controller and Host Subsystem, and
-// BluetoothDeviceChromeOS which presents the pairing logic to the application.
-class BluetoothPairingChromeOS {
+// BluetoothDeviceBlueZ which presents the pairing logic to the application.
+class BluetoothPairingBlueZ {
  public:
-  BluetoothPairingChromeOS(
-      BluetoothDeviceChromeOS* device,
+  BluetoothPairingBlueZ(
+      BluetoothDeviceBlueZ* device,
       device::BluetoothDevice::PairingDelegate* pairing_delegate);
-  ~BluetoothPairingChromeOS();
+  ~BluetoothPairingBlueZ();
 
   // Indicates whether the device is currently pairing and expecting a
   // Passkey to be returned.
@@ -117,8 +118,8 @@
   bool RunPairingCallbacks(
       bluez::BluetoothAgentServiceProvider::Delegate::Status status);
 
-  // The underlying BluetoothDeviceChromeOS that owns this pairing context.
-  BluetoothDeviceChromeOS* device_;
+  // The underlying BluetoothDeviceBlueZ that owns this pairing context.
+  BluetoothDeviceBlueZ* device_;
 
   // UI Pairing Delegate to make method calls on, this must live as long as
   // the object capturing the PairingContext.
@@ -130,7 +131,7 @@
   bool pairing_delegate_used_;
 
   // During pairing these callbacks are set to those provided by method calls
-  // made on the BluetoothAdapterChromeOS instance by its respective
+  // made on the BluetoothAdapterBlueZ instance by its respective
   // bluez::BluetoothAgentServiceProvider instance, and are called by our own
   // method calls such as SetPinCode() and SetPasskey().
   bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback
@@ -140,9 +141,9 @@
   bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback
       confirmation_callback_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothPairingChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothPairingBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
index f0825f6b..8d5868b5 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
+#include "device/bluetooth/bluetooth_gatt_notify_session_android.h"
 #include "device/bluetooth/bluetooth_remote_gatt_service_android.h"
 #include "jni/ChromeBluetoothRemoteGattCharacteristic_jni.h"
 
@@ -54,7 +55,7 @@
 }
 
 std::string BluetoothRemoteGattCharacteristicAndroid::GetIdentifier() const {
-  return instanceId_;
+  return instance_id_;
 }
 
 BluetoothUUID BluetoothRemoteGattCharacteristicAndroid::GetUUID() const {
@@ -123,7 +124,20 @@
 void BluetoothRemoteGattCharacteristicAndroid::StartNotifySession(
     const NotifySessionCallback& callback,
     const ErrorCallback& error_callback) {
-  NOTIMPLEMENTED();
+  // TODO(crbug.com/551634): Check characteristic properties and return a better
+  // error code if notifications aren't permitted.
+  if (Java_ChromeBluetoothRemoteGattCharacteristic_startNotifySession(
+          AttachCurrentThread(), j_characteristic_.obj())) {
+    scoped_ptr<device::BluetoothGattNotifySession> notify_session(
+        new BluetoothGattNotifySessionAndroid(instance_id_));
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(callback, base::Passed(&notify_session)));
+  } else {
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(error_callback,
+                   BluetoothRemoteGattServiceAndroid::GATT_ERROR_FAILED));
+  }
 }
 
 void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic(
@@ -215,6 +229,6 @@
 
 BluetoothRemoteGattCharacteristicAndroid::
     BluetoothRemoteGattCharacteristicAndroid(const std::string& instanceId)
-    : instanceId_(instanceId) {}
+    : instance_id_(instanceId) {}
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h
index b5c85a3..b386e7e 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h
@@ -14,6 +14,9 @@
 // BluetoothRemoteGattCharacteristicAndroid along with its owned Java class
 // org.chromium.device.bluetooth.ChromeBluetoothRemoteGattCharacteristic
 // implement BluetootGattCharacteristic.
+//
+// TODO(crbug.com/551634): When notifications are enabled characteristic updates
+// should call observers' GattCharacteristicValueChanged.
 class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicAndroid
     : public BluetoothGattCharacteristic {
  public:
@@ -75,7 +78,7 @@
   base::android::ScopedJavaGlobalRef<jobject> j_characteristic_;
 
   // Adapter unique instance ID.
-  std::string instanceId_;
+  std::string instance_id_;
 
   // ReadRemoteCharacteristic callbacks and pending state.
   bool read_pending_ = false;
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.cc
similarity index 75%
rename from device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
rename to device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.cc
index 7374f160..75c6f1a 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.cc
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h"
 
 #include <limits>
 
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #include "device/bluetooth/bluetooth_device.h"
-#include "device/bluetooth/bluetooth_gatt_notify_session_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
+#include "device/bluetooth/bluetooth_gatt_notify_session_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -33,10 +33,9 @@
 
 }  // namespace
 
-BluetoothRemoteGattCharacteristicChromeOS::
-    BluetoothRemoteGattCharacteristicChromeOS(
-        BluetoothRemoteGattServiceChromeOS* service,
-        const dbus::ObjectPath& object_path)
+BluetoothRemoteGattCharacteristicBlueZ::BluetoothRemoteGattCharacteristicBlueZ(
+    BluetoothRemoteGattServiceBlueZ* service,
+    const dbus::ObjectPath& object_path)
     : object_path_(object_path),
       service_(service),
       num_notify_sessions_(0),
@@ -58,8 +57,8 @@
     GattDescriptorAdded(*iter);
 }
 
-BluetoothRemoteGattCharacteristicChromeOS::
-    ~BluetoothRemoteGattCharacteristicChromeOS() {
+BluetoothRemoteGattCharacteristicBlueZ::
+    ~BluetoothRemoteGattCharacteristicBlueZ() {
   bluez::BluezDBusManager::Get()
       ->GetBluetoothGattDescriptorClient()
       ->RemoveObserver(this);
@@ -78,12 +77,11 @@
   }
 }
 
-std::string BluetoothRemoteGattCharacteristicChromeOS::GetIdentifier() const {
+std::string BluetoothRemoteGattCharacteristicBlueZ::GetIdentifier() const {
   return object_path_.value();
 }
 
-device::BluetoothUUID
-BluetoothRemoteGattCharacteristicChromeOS::GetUUID() const {
+device::BluetoothUUID BluetoothRemoteGattCharacteristicBlueZ::GetUUID() const {
   bluez::BluetoothGattCharacteristicClient::Properties* properties =
       bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
@@ -92,12 +90,12 @@
   return device::BluetoothUUID(properties->uuid.value());
 }
 
-bool BluetoothRemoteGattCharacteristicChromeOS::IsLocal() const {
+bool BluetoothRemoteGattCharacteristicBlueZ::IsLocal() const {
   return false;
 }
 
-const std::vector<uint8>&
-BluetoothRemoteGattCharacteristicChromeOS::GetValue() const {
+const std::vector<uint8>& BluetoothRemoteGattCharacteristicBlueZ::GetValue()
+    const {
   bluez::BluetoothGattCharacteristicClient::Properties* properties =
       bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
@@ -109,12 +107,12 @@
 }
 
 device::BluetoothGattService*
-BluetoothRemoteGattCharacteristicChromeOS::GetService() const {
+BluetoothRemoteGattCharacteristicBlueZ::GetService() const {
   return service_;
 }
 
 device::BluetoothGattCharacteristic::Properties
-BluetoothRemoteGattCharacteristicChromeOS::GetProperties() const {
+BluetoothRemoteGattCharacteristicBlueZ::GetProperties() const {
   bluez::BluetoothGattCharacteristicClient::Properties* properties =
       bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
@@ -124,8 +122,7 @@
   Properties props = PROPERTY_NONE;
   const std::vector<std::string>& flags = properties->flags.value();
   for (std::vector<std::string>::const_iterator iter = flags.begin();
-       iter != flags.end();
-       ++iter) {
+       iter != flags.end(); ++iter) {
     if (*iter == bluetooth_gatt_characteristic::kFlagBroadcast)
       props |= PROPERTY_BROADCAST;
     if (*iter == bluetooth_gatt_characteristic::kFlagRead)
@@ -152,13 +149,13 @@
 }
 
 device::BluetoothGattCharacteristic::Permissions
-BluetoothRemoteGattCharacteristicChromeOS::GetPermissions() const {
+BluetoothRemoteGattCharacteristicBlueZ::GetPermissions() const {
   // TODO(armansito): Once BlueZ defines the permissions, return the correct
   // values here.
   return PERMISSION_NONE;
 }
 
-bool BluetoothRemoteGattCharacteristicChromeOS::IsNotifying() const {
+bool BluetoothRemoteGattCharacteristicBlueZ::IsNotifying() const {
   bluez::BluetoothGattCharacteristicClient::Properties* properties =
       bluez::BluezDBusManager::Get()
           ->GetBluetoothGattCharacteristicClient()
@@ -169,7 +166,7 @@
 }
 
 std::vector<device::BluetoothGattDescriptor*>
-BluetoothRemoteGattCharacteristicChromeOS::GetDescriptors() const {
+BluetoothRemoteGattCharacteristicBlueZ::GetDescriptors() const {
   std::vector<device::BluetoothGattDescriptor*> descriptors;
   for (DescriptorMap::const_iterator iter = descriptors_.begin();
        iter != descriptors_.end(); ++iter)
@@ -178,7 +175,7 @@
 }
 
 device::BluetoothGattDescriptor*
-BluetoothRemoteGattCharacteristicChromeOS::GetDescriptor(
+BluetoothRemoteGattCharacteristicBlueZ::GetDescriptor(
     const std::string& identifier) const {
   DescriptorMap::const_iterator iter =
       descriptors_.find(dbus::ObjectPath(identifier));
@@ -187,19 +184,19 @@
   return iter->second;
 }
 
-bool BluetoothRemoteGattCharacteristicChromeOS::AddDescriptor(
+bool BluetoothRemoteGattCharacteristicBlueZ::AddDescriptor(
     device::BluetoothGattDescriptor* descriptor) {
   VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic.";
   return false;
 }
 
-bool BluetoothRemoteGattCharacteristicChromeOS::UpdateValue(
+bool BluetoothRemoteGattCharacteristicBlueZ::UpdateValue(
     const std::vector<uint8>& value) {
   VLOG(1) << "Cannot update the value of a remote GATT characteristic.";
   return false;
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::ReadRemoteCharacteristic(
+void BluetoothRemoteGattCharacteristicBlueZ::ReadRemoteCharacteristic(
     const ValueCallback& callback,
     const ErrorCallback& error_callback) {
   VLOG(1) << "Sending GATT characteristic read request to characteristic: "
@@ -208,13 +205,12 @@
 
   bluez::BluezDBusManager::Get()
       ->GetBluetoothGattCharacteristicClient()
-      ->ReadValue(
-          object_path_, callback,
-          base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError,
-                     weak_ptr_factory_.GetWeakPtr(), error_callback));
+      ->ReadValue(object_path_, callback,
+                  base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError,
+                             weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic(
+void BluetoothRemoteGattCharacteristicBlueZ::WriteRemoteCharacteristic(
     const std::vector<uint8>& new_value,
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
@@ -224,13 +220,12 @@
 
   bluez::BluezDBusManager::Get()
       ->GetBluetoothGattCharacteristicClient()
-      ->WriteValue(
-          object_path_, new_value, callback,
-          base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError,
-                     weak_ptr_factory_.GetWeakPtr(), error_callback));
+      ->WriteValue(object_path_, new_value, callback,
+                   base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnError,
+                              weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::StartNotifySession(
+void BluetoothRemoteGattCharacteristicBlueZ::StartNotifySession(
     const NotifySessionCallback& callback,
     const ErrorCallback& error_callback) {
   VLOG(1) << __func__;
@@ -253,12 +248,9 @@
       DCHECK(service_->GetAdapter());
       DCHECK(service_->GetDevice());
       scoped_ptr<device::BluetoothGattNotifySession> session(
-          new BluetoothGattNotifySessionChromeOS(
-              service_->GetAdapter(),
-              service_->GetDevice()->GetAddress(),
-              service_->GetIdentifier(),
-              GetIdentifier(),
-              object_path_));
+          new BluetoothGattNotifySessionBlueZ(
+              service_->GetAdapter(), service_->GetDevice()->GetAddress(),
+              service_->GetIdentifier(), GetIdentifier(), object_path_));
       callback.Run(session.Pass());
       return;
     }
@@ -278,14 +270,14 @@
       ->StartNotify(
           object_path_,
           base::Bind(
-              &BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifySuccess,
+              &BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifySuccess,
               weak_ptr_factory_.GetWeakPtr(), callback),
           base::Bind(
-              &BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifyError,
+              &BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifyError,
               weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::RemoveNotifySession(
+void BluetoothRemoteGattCharacteristicBlueZ::RemoveNotifySession(
     const base::Closure& callback) {
   VLOG(1) << __func__;
 
@@ -316,14 +308,13 @@
       ->StopNotify(
           object_path_,
           base::Bind(
-              &BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifySuccess,
+              &BluetoothRemoteGattCharacteristicBlueZ::OnStopNotifySuccess,
               weak_ptr_factory_.GetWeakPtr(), callback),
-          base::Bind(
-              &BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifyError,
-              weak_ptr_factory_.GetWeakPtr(), callback));
+          base::Bind(&BluetoothRemoteGattCharacteristicBlueZ::OnStopNotifyError,
+                     weak_ptr_factory_.GetWeakPtr(), callback));
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorAdded(
+void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorAdded(
     const dbus::ObjectPath& object_path) {
   if (descriptors_.find(object_path) != descriptors_.end()) {
     VLOG(1) << "Remote GATT characteristic descriptor already exists: "
@@ -344,8 +335,8 @@
   VLOG(1) << "Adding new remote GATT descriptor for GATT characteristic: "
           << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
 
-  BluetoothRemoteGattDescriptorChromeOS* descriptor =
-      new BluetoothRemoteGattDescriptorChromeOS(this, object_path);
+  BluetoothRemoteGattDescriptorBlueZ* descriptor =
+      new BluetoothRemoteGattDescriptorBlueZ(this, object_path);
   descriptors_[object_path] = descriptor;
   DCHECK(descriptor->GetIdentifier() == object_path.value());
   DCHECK(descriptor->GetUUID().IsValid());
@@ -354,7 +345,7 @@
   service_->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */);
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorRemoved(
+void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorRemoved(
     const dbus::ObjectPath& object_path) {
   DescriptorMap::iterator iter = descriptors_.find(object_path);
   if (iter == descriptors_.end()) {
@@ -365,7 +356,7 @@
   VLOG(1) << "Removing remote GATT descriptor from characteristic: "
           << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
 
-  BluetoothRemoteGattDescriptorChromeOS* descriptor = iter->second;
+  BluetoothRemoteGattDescriptorBlueZ* descriptor = iter->second;
   DCHECK(descriptor->object_path() == object_path);
   descriptors_.erase(iter);
 
@@ -375,7 +366,7 @@
   delete descriptor;
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorPropertyChanged(
+void BluetoothRemoteGattCharacteristicBlueZ::GattDescriptorPropertyChanged(
     const dbus::ObjectPath& object_path,
     const std::string& property_name) {
   DescriptorMap::iterator iter = descriptors_.find(object_path);
@@ -399,17 +390,17 @@
                                          properties->value.value());
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::OnError(
+void BluetoothRemoteGattCharacteristicBlueZ::OnError(
     const ErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
-  VLOG(1) << "Operation failed: " << error_name << ", message: "
-          << error_message;
+  VLOG(1) << "Operation failed: " << error_name
+          << ", message: " << error_message;
   error_callback.Run(
-      BluetoothRemoteGattServiceChromeOS::DBusErrorToServiceError(error_name));
+      BluetoothRemoteGattServiceBlueZ::DBusErrorToServiceError(error_name));
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifySuccess(
+void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifySuccess(
     const NotifySessionCallback& callback) {
   VLOG(1) << "Started notifications from characteristic: "
           << object_path_.value();
@@ -423,18 +414,15 @@
   DCHECK(service_);
   DCHECK(service_->GetDevice());
   scoped_ptr<device::BluetoothGattNotifySession> session(
-      new BluetoothGattNotifySessionChromeOS(
-          service_->GetAdapter(),
-          service_->GetDevice()->GetAddress(),
-          service_->GetIdentifier(),
-          GetIdentifier(),
-          object_path_));
+      new BluetoothGattNotifySessionBlueZ(
+          service_->GetAdapter(), service_->GetDevice()->GetAddress(),
+          service_->GetIdentifier(), GetIdentifier(), object_path_));
   callback.Run(session.Pass());
 
   ProcessStartNotifyQueue();
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifyError(
+void BluetoothRemoteGattCharacteristicBlueZ::OnStartNotifyError(
     const ErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -447,12 +435,12 @@
   notify_call_pending_ = false;
 
   error_callback.Run(
-      BluetoothRemoteGattServiceChromeOS::DBusErrorToServiceError(error_name));
+      BluetoothRemoteGattServiceBlueZ::DBusErrorToServiceError(error_name));
 
   ProcessStartNotifyQueue();
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifySuccess(
+void BluetoothRemoteGattCharacteristicBlueZ::OnStopNotifySuccess(
     const base::Closure& callback) {
   DCHECK(notify_call_pending_);
   DCHECK(num_notify_sessions_ == 1);
@@ -464,7 +452,7 @@
   ProcessStartNotifyQueue();
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifyError(
+void BluetoothRemoteGattCharacteristicBlueZ::OnStopNotifyError(
     const base::Closure& callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -476,7 +464,7 @@
   OnStopNotifySuccess(callback);
 }
 
-void BluetoothRemoteGattCharacteristicChromeOS::ProcessStartNotifyQueue() {
+void BluetoothRemoteGattCharacteristicBlueZ::ProcessStartNotifyQueue() {
   while (!pending_start_notify_calls_.empty()) {
     PendingStartNotifyCall callbacks = pending_start_notify_calls_.front();
     pending_start_notify_calls_.pop();
@@ -484,4 +472,4 @@
   }
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h
similarity index 86%
rename from device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
rename to device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h
index 361b3197..664f0fcc 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_BLUEZ_H_
 
 #include <map>
 #include <queue>
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
@@ -24,15 +25,15 @@
 
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothRemoteGattDescriptorChromeOS;
-class BluetoothRemoteGattServiceChromeOS;
+class BluetoothRemoteGattDescriptorBlueZ;
+class BluetoothRemoteGattServiceBlueZ;
 
-// The BluetoothRemoteGattCharacteristicChromeOS class implements
+// The BluetoothRemoteGattCharacteristicBlueZ class implements
 // BluetoothGattCharacteristic for remote GATT characteristics on the Chrome OS
 // platform.
-class BluetoothRemoteGattCharacteristicChromeOS
+class BluetoothRemoteGattCharacteristicBlueZ
     : public device::BluetoothGattCharacteristic,
       public bluez::BluetoothGattDescriptorClient::Observer {
  public:
@@ -68,15 +69,15 @@
   const dbus::ObjectPath& object_path() const { return object_path_; }
 
  private:
-  friend class BluetoothRemoteGattServiceChromeOS;
+  friend class BluetoothRemoteGattServiceBlueZ;
 
   typedef std::pair<NotifySessionCallback, ErrorCallback>
       PendingStartNotifyCall;
 
-  BluetoothRemoteGattCharacteristicChromeOS(
-      BluetoothRemoteGattServiceChromeOS* service,
+  BluetoothRemoteGattCharacteristicBlueZ(
+      BluetoothRemoteGattServiceBlueZ* service,
       const dbus::ObjectPath& object_path);
-  ~BluetoothRemoteGattCharacteristicChromeOS() override;
+  ~BluetoothRemoteGattCharacteristicBlueZ() override;
 
   // bluez::BluetoothGattDescriptorClient::Observer overrides.
   void GattDescriptorAdded(const dbus::ObjectPath& object_path) override;
@@ -117,7 +118,7 @@
   dbus::ObjectPath object_path_;
 
   // The GATT service this GATT characteristic belongs to.
-  BluetoothRemoteGattServiceChromeOS* service_;
+  BluetoothRemoteGattServiceBlueZ* service_;
 
   // The total number of currently active value update sessions.
   size_t num_notify_sessions_;
@@ -133,18 +134,18 @@
   // this characteristic. Since the Chrome OS implementation uses object paths
   // as unique identifiers, we also use this mapping to return descriptors by
   // identifier.
-  typedef std::map<dbus::ObjectPath, BluetoothRemoteGattDescriptorChromeOS*>
+  typedef std::map<dbus::ObjectPath, BluetoothRemoteGattDescriptorBlueZ*>
       DescriptorMap;
   DescriptorMap descriptors_;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothRemoteGattCharacteristicChromeOS>
+  base::WeakPtrFactory<BluetoothRemoteGattCharacteristicBlueZ>
       weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.cc
similarity index 65%
rename from device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc
rename to device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.cc
index f864c3b..4bf9ab0 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.cc
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
+#include "device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h"
 
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
-#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h"
 #include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -28,8 +28,8 @@
 
 }  // namespace
 
-BluetoothRemoteGattDescriptorChromeOS::BluetoothRemoteGattDescriptorChromeOS(
-    BluetoothRemoteGattCharacteristicChromeOS* characteristic,
+BluetoothRemoteGattDescriptorBlueZ::BluetoothRemoteGattDescriptorBlueZ(
+    BluetoothRemoteGattCharacteristicBlueZ* characteristic,
     const dbus::ObjectPath& object_path)
     : object_path_(object_path),
       characteristic_(characteristic),
@@ -38,15 +38,13 @@
           << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
 }
 
-BluetoothRemoteGattDescriptorChromeOS::
-    ~BluetoothRemoteGattDescriptorChromeOS() {
-}
+BluetoothRemoteGattDescriptorBlueZ::~BluetoothRemoteGattDescriptorBlueZ() {}
 
-std::string BluetoothRemoteGattDescriptorChromeOS::GetIdentifier() const {
+std::string BluetoothRemoteGattDescriptorBlueZ::GetIdentifier() const {
   return object_path_.value();
 }
 
-device::BluetoothUUID BluetoothRemoteGattDescriptorChromeOS::GetUUID() const {
+device::BluetoothUUID BluetoothRemoteGattDescriptorBlueZ::GetUUID() const {
   bluez::BluetoothGattDescriptorClient::Properties* properties =
       bluez::BluezDBusManager::Get()
           ->GetBluetoothGattDescriptorClient()
@@ -55,12 +53,11 @@
   return device::BluetoothUUID(properties->uuid.value());
 }
 
-bool BluetoothRemoteGattDescriptorChromeOS::IsLocal() const {
+bool BluetoothRemoteGattDescriptorBlueZ::IsLocal() const {
   return false;
 }
 
-const std::vector<uint8>&
-BluetoothRemoteGattDescriptorChromeOS::GetValue() const {
+const std::vector<uint8>& BluetoothRemoteGattDescriptorBlueZ::GetValue() const {
   bluez::BluetoothGattDescriptorClient::Properties* properties =
       bluez::BluezDBusManager::Get()
           ->GetBluetoothGattDescriptorClient()
@@ -72,47 +69,47 @@
 }
 
 device::BluetoothGattCharacteristic*
-BluetoothRemoteGattDescriptorChromeOS::GetCharacteristic() const {
+BluetoothRemoteGattDescriptorBlueZ::GetCharacteristic() const {
   return characteristic_;
 }
 
 device::BluetoothGattCharacteristic::Permissions
-BluetoothRemoteGattDescriptorChromeOS::GetPermissions() const {
+BluetoothRemoteGattDescriptorBlueZ::GetPermissions() const {
   // TODO(armansito): Once BlueZ defines the permissions, return the correct
   // values here.
   return device::BluetoothGattCharacteristic::PERMISSION_NONE;
 }
 
-void BluetoothRemoteGattDescriptorChromeOS::ReadRemoteDescriptor(
+void BluetoothRemoteGattDescriptorBlueZ::ReadRemoteDescriptor(
     const ValueCallback& callback,
     const ErrorCallback& error_callback) {
   VLOG(1) << "Sending GATT characteristic descriptor read request to "
-          << "descriptor: " << GetIdentifier() << ", UUID: "
-          << GetUUID().canonical_value();
+          << "descriptor: " << GetIdentifier()
+          << ", UUID: " << GetUUID().canonical_value();
 
   bluez::BluezDBusManager::Get()->GetBluetoothGattDescriptorClient()->ReadValue(
       object_path_, callback,
-      base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
+      base::Bind(&BluetoothRemoteGattDescriptorBlueZ::OnError,
                  weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothRemoteGattDescriptorChromeOS::WriteRemoteDescriptor(
+void BluetoothRemoteGattDescriptorBlueZ::WriteRemoteDescriptor(
     const std::vector<uint8>& new_value,
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
   VLOG(1) << "Sending GATT characteristic descriptor write request to "
-          << "characteristic: " << GetIdentifier() << ", UUID: "
-          << GetUUID().canonical_value() << ", with value: "
-          << new_value << ".";
+          << "characteristic: " << GetIdentifier()
+          << ", UUID: " << GetUUID().canonical_value()
+          << ", with value: " << new_value << ".";
 
   bluez::BluezDBusManager::Get()
       ->GetBluetoothGattDescriptorClient()
       ->WriteValue(object_path_, new_value, callback,
-                   base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
+                   base::Bind(&BluetoothRemoteGattDescriptorBlueZ::OnError,
                               weak_ptr_factory_.GetWeakPtr(), error_callback));
 }
 
-void BluetoothRemoteGattDescriptorChromeOS::OnError(
+void BluetoothRemoteGattDescriptorBlueZ::OnError(
     const ErrorCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -120,7 +117,7 @@
           << ", message: " << error_message;
 
   error_callback.Run(
-      BluetoothRemoteGattServiceChromeOS::DBusErrorToServiceError(error_name));
+      BluetoothRemoteGattServiceBlueZ::DBusErrorToServiceError(error_name));
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h
similarity index 70%
rename from device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h
rename to device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h
index b32dd87..90afaea 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_DESCRIPTOR_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_DESCRIPTOR_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_DESCRIPTOR_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_DESCRIPTOR_BLUEZ_H_
 
 #include <string>
 #include <vector>
 
+#include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_gatt_descriptor.h"
@@ -19,14 +20,14 @@
 
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothRemoteGattCharacteristicChromeOS;
+class BluetoothRemoteGattCharacteristicBlueZ;
 
-// The BluetoothRemoteGattDescriptorChromeOS class implements
+// The BluetoothRemoteGattDescriptorBlueZ class implements
 // BluetoothGattDescriptor for remote GATT characteristic descriptors on the
 // Chrome OS platform.
-class BluetoothRemoteGattDescriptorChromeOS
+class BluetoothRemoteGattDescriptorBlueZ
     : public device::BluetoothGattDescriptor {
  public:
   // device::BluetoothGattDescriptor overrides.
@@ -47,12 +48,12 @@
   const dbus::ObjectPath& object_path() const { return object_path_; }
 
  private:
-  friend class BluetoothRemoteGattCharacteristicChromeOS;
+  friend class BluetoothRemoteGattCharacteristicBlueZ;
 
-  BluetoothRemoteGattDescriptorChromeOS(
-      BluetoothRemoteGattCharacteristicChromeOS* characteristic,
+  BluetoothRemoteGattDescriptorBlueZ(
+      BluetoothRemoteGattCharacteristicBlueZ* characteristic,
       const dbus::ObjectPath& object_path);
-  ~BluetoothRemoteGattDescriptorChromeOS() override;
+  ~BluetoothRemoteGattDescriptorBlueZ() override;
 
   // Called by dbus:: on unsuccessful completion of a request to read or write
   // the descriptor value.
@@ -64,15 +65,15 @@
   dbus::ObjectPath object_path_;
 
   // The GATT characteristic this descriptor belongs to.
-  BluetoothRemoteGattCharacteristicChromeOS* characteristic_;
+  BluetoothRemoteGattCharacteristicBlueZ* characteristic_;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothRemoteGattDescriptorChromeOS> weak_ptr_factory_;
+  base::WeakPtrFactory<BluetoothRemoteGattDescriptorBlueZ> weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptorChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptorBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_DESCRIPTOR_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_DESCRIPTOR_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_service_bluez.cc
similarity index 79%
rename from device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
rename to device/bluetooth/bluetooth_remote_gatt_service_bluez.cc
index 8a57fa2..e3fb5b1 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_service_bluez.cc
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_bluez.h"
 
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
-#include "device/bluetooth/bluetooth_device_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
-#include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
+#include "device/bluetooth/bluetooth_device_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_bluez.h"
+#include "device/bluetooth/bluetooth_remote_gatt_descriptor_bluez.h"
 #include "device/bluetooth/dbus/bluetooth_gatt_service_client.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 
-namespace chromeos {
+namespace bluez {
 
 namespace {
 
@@ -28,9 +28,9 @@
 
 }  // namespace
 
-BluetoothRemoteGattServiceChromeOS::BluetoothRemoteGattServiceChromeOS(
-    BluetoothAdapterChromeOS* adapter,
-    BluetoothDeviceChromeOS* device,
+BluetoothRemoteGattServiceBlueZ::BluetoothRemoteGattServiceBlueZ(
+    BluetoothAdapterBlueZ* adapter,
+    BluetoothDeviceBlueZ* device,
     const dbus::ObjectPath& object_path)
     : object_path_(object_path),
       adapter_(adapter),
@@ -57,7 +57,7 @@
     GattCharacteristicAdded(*iter);
 }
 
-BluetoothRemoteGattServiceChromeOS::~BluetoothRemoteGattServiceChromeOS() {
+BluetoothRemoteGattServiceBlueZ::~BluetoothRemoteGattServiceBlueZ() {
   bluez::BluezDBusManager::Get()
       ->GetBluetoothGattServiceClient()
       ->RemoveObserver(this);
@@ -79,11 +79,11 @@
   }
 }
 
-std::string BluetoothRemoteGattServiceChromeOS::GetIdentifier() const {
+std::string BluetoothRemoteGattServiceBlueZ::GetIdentifier() const {
   return object_path_.value();
 }
 
-device::BluetoothUUID BluetoothRemoteGattServiceChromeOS::GetUUID() const {
+device::BluetoothUUID BluetoothRemoteGattServiceBlueZ::GetUUID() const {
   bluez::BluetoothGattServiceClient::Properties* properties =
       bluez::BluezDBusManager::Get()
           ->GetBluetoothGattServiceClient()
@@ -92,11 +92,11 @@
   return device::BluetoothUUID(properties->uuid.value());
 }
 
-bool BluetoothRemoteGattServiceChromeOS::IsLocal() const {
+bool BluetoothRemoteGattServiceBlueZ::IsLocal() const {
   return false;
 }
 
-bool BluetoothRemoteGattServiceChromeOS::IsPrimary() const {
+bool BluetoothRemoteGattServiceBlueZ::IsPrimary() const {
   bluez::BluetoothGattServiceClient::Properties* properties =
       bluez::BluezDBusManager::Get()
           ->GetBluetoothGattServiceClient()
@@ -105,12 +105,12 @@
   return properties->primary.value();
 }
 
-device::BluetoothDevice* BluetoothRemoteGattServiceChromeOS::GetDevice() const {
+device::BluetoothDevice* BluetoothRemoteGattServiceBlueZ::GetDevice() const {
   return device_;
 }
 
 std::vector<device::BluetoothGattCharacteristic*>
-BluetoothRemoteGattServiceChromeOS::GetCharacteristics() const {
+BluetoothRemoteGattServiceBlueZ::GetCharacteristics() const {
   std::vector<device::BluetoothGattCharacteristic*> characteristics;
   for (CharacteristicMap::const_iterator iter = characteristics_.begin();
        iter != characteristics_.end(); ++iter) {
@@ -120,13 +120,13 @@
 }
 
 std::vector<device::BluetoothGattService*>
-BluetoothRemoteGattServiceChromeOS::GetIncludedServices() const {
+BluetoothRemoteGattServiceBlueZ::GetIncludedServices() const {
   // TODO(armansito): Return the actual included services here.
   return std::vector<device::BluetoothGattService*>();
 }
 
 device::BluetoothGattCharacteristic*
-BluetoothRemoteGattServiceChromeOS::GetCharacteristic(
+BluetoothRemoteGattServiceBlueZ::GetCharacteristic(
     const std::string& identifier) const {
   CharacteristicMap::const_iterator iter =
       characteristics_.find(dbus::ObjectPath(identifier));
@@ -135,26 +135,26 @@
   return iter->second;
 }
 
-bool BluetoothRemoteGattServiceChromeOS::AddCharacteristic(
+bool BluetoothRemoteGattServiceBlueZ::AddCharacteristic(
     device::BluetoothGattCharacteristic* characteristic) {
   VLOG(1) << "Characteristics cannot be added to a remote GATT service.";
   return false;
 }
 
-bool BluetoothRemoteGattServiceChromeOS::AddIncludedService(
+bool BluetoothRemoteGattServiceBlueZ::AddIncludedService(
     device::BluetoothGattService* service) {
   VLOG(1) << "Included services cannot be added to a remote GATT service.";
   return false;
 }
 
-void BluetoothRemoteGattServiceChromeOS::Register(
+void BluetoothRemoteGattServiceBlueZ::Register(
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
   VLOG(1) << "A remote GATT service cannot be registered.";
   error_callback.Run();
 }
 
-void BluetoothRemoteGattServiceChromeOS::Unregister(
+void BluetoothRemoteGattServiceBlueZ::Unregister(
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
   VLOG(1) << "A remote GATT service cannot be unregistered.";
@@ -163,7 +163,7 @@
 
 // static
 device::BluetoothGattService::GattErrorCode
-BluetoothRemoteGattServiceChromeOS::DBusErrorToServiceError(
+BluetoothRemoteGattServiceBlueZ::DBusErrorToServiceError(
     std::string error_name) {
   device::BluetoothGattService::GattErrorCode code = GATT_ERROR_UNKNOWN;
   if (error_name == kErrorFailed) {
@@ -184,12 +184,11 @@
   return code;
 }
 
-BluetoothAdapterChromeOS*
-BluetoothRemoteGattServiceChromeOS::GetAdapter() const {
+BluetoothAdapterBlueZ* BluetoothRemoteGattServiceBlueZ::GetAdapter() const {
   return adapter_;
 }
 
-void BluetoothRemoteGattServiceChromeOS::NotifyServiceChanged() {
+void BluetoothRemoteGattServiceBlueZ::NotifyServiceChanged() {
   // Don't send service changed unless we know that all characteristics have
   // already been discovered. This is to prevent spammy events before sending
   // out the first Gatt
@@ -200,9 +199,9 @@
   adapter_->NotifyGattServiceChanged(this);
 }
 
-void BluetoothRemoteGattServiceChromeOS::NotifyDescriptorAddedOrRemoved(
-    BluetoothRemoteGattCharacteristicChromeOS* characteristic,
-    BluetoothRemoteGattDescriptorChromeOS* descriptor,
+void BluetoothRemoteGattServiceBlueZ::NotifyDescriptorAddedOrRemoved(
+    BluetoothRemoteGattCharacteristicBlueZ* characteristic,
+    BluetoothRemoteGattDescriptorBlueZ* descriptor,
     bool added) {
   DCHECK(characteristic->GetService() == this);
   DCHECK(descriptor->GetCharacteristic() == characteristic);
@@ -216,9 +215,9 @@
   adapter_->NotifyGattDescriptorRemoved(descriptor);
 }
 
-void BluetoothRemoteGattServiceChromeOS::NotifyDescriptorValueChanged(
-    BluetoothRemoteGattCharacteristicChromeOS* characteristic,
-    BluetoothRemoteGattDescriptorChromeOS* descriptor,
+void BluetoothRemoteGattServiceBlueZ::NotifyDescriptorValueChanged(
+    BluetoothRemoteGattCharacteristicBlueZ* characteristic,
+    BluetoothRemoteGattDescriptorBlueZ* descriptor,
     const std::vector<uint8>& value) {
   DCHECK(characteristic->GetService() == this);
   DCHECK(descriptor->GetCharacteristic() == characteristic);
@@ -226,9 +225,9 @@
   adapter_->NotifyGattDescriptorValueChanged(descriptor, value);
 }
 
-void BluetoothRemoteGattServiceChromeOS::GattServicePropertyChanged(
+void BluetoothRemoteGattServiceBlueZ::GattServicePropertyChanged(
     const dbus::ObjectPath& object_path,
-    const std::string& property_name){
+    const std::string& property_name) {
   if (object_path != object_path_)
     return;
 
@@ -255,7 +254,7 @@
   adapter_->NotifyGattDiscoveryComplete(this);
 }
 
-void BluetoothRemoteGattServiceChromeOS::GattCharacteristicAdded(
+void BluetoothRemoteGattServiceBlueZ::GattCharacteristicAdded(
     const dbus::ObjectPath& object_path) {
   if (characteristics_.find(object_path) != characteristics_.end()) {
     VLOG(1) << "Remote GATT characteristic already exists: "
@@ -276,8 +275,8 @@
   VLOG(1) << "Adding new remote GATT characteristic for GATT service: "
           << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
 
-  BluetoothRemoteGattCharacteristicChromeOS* characteristic =
-      new BluetoothRemoteGattCharacteristicChromeOS(this, object_path);
+  BluetoothRemoteGattCharacteristicBlueZ* characteristic =
+      new BluetoothRemoteGattCharacteristicBlueZ(this, object_path);
   characteristics_[object_path] = characteristic;
   DCHECK(characteristic->GetIdentifier() == object_path.value());
   DCHECK(characteristic->GetUUID().IsValid());
@@ -286,7 +285,7 @@
   adapter_->NotifyGattCharacteristicAdded(characteristic);
 }
 
-void BluetoothRemoteGattServiceChromeOS::GattCharacteristicRemoved(
+void BluetoothRemoteGattServiceBlueZ::GattCharacteristicRemoved(
     const dbus::ObjectPath& object_path) {
   CharacteristicMap::iterator iter = characteristics_.find(object_path);
   if (iter == characteristics_.end()) {
@@ -297,7 +296,7 @@
   VLOG(1) << "Removing remote GATT characteristic from service: "
           << GetIdentifier() << ", UUID: " << GetUUID().canonical_value();
 
-  BluetoothRemoteGattCharacteristicChromeOS* characteristic = iter->second;
+  BluetoothRemoteGattCharacteristicBlueZ* characteristic = iter->second;
   DCHECK(characteristic->object_path() == object_path);
   characteristics_.erase(iter);
 
@@ -307,7 +306,7 @@
   delete characteristic;
 }
 
-void BluetoothRemoteGattServiceChromeOS::GattCharacteristicPropertyChanged(
+void BluetoothRemoteGattServiceBlueZ::GattCharacteristicPropertyChanged(
     const dbus::ObjectPath& object_path,
     const std::string& property_name) {
   CharacteristicMap::iterator iter = characteristics_.find(object_path);
@@ -336,4 +335,4 @@
                                                    properties->value.value());
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_service_bluez.h
similarity index 73%
rename from device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
rename to device/bluetooth/bluetooth_remote_gatt_service_bluez.h
index bc35cb7..83222f0d 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_bluez.h
@@ -2,13 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_BLUEZ_H_
 
 #include <map>
 #include <string>
 #include <vector>
 
+#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
@@ -25,16 +26,16 @@
 
 }  // namespace device
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothAdapterChromeOS;
-class BluetoothDeviceChromeOS;
-class BluetoothRemoteGattCharacteristicChromeOS;
-class BluetoothRemoteGattDescriptorChromeOS;
+class BluetoothAdapterBlueZ;
+class BluetoothDeviceBlueZ;
+class BluetoothRemoteGattCharacteristicBlueZ;
+class BluetoothRemoteGattDescriptorBlueZ;
 
-// The BluetoothRemoteGattServiceChromeOS class implements BluetootGattService
+// The BluetoothRemoteGattServiceBlueZ class implements BluetootGattService
 // for remote GATT services on the Chrome OS platform.
-class BluetoothRemoteGattServiceChromeOS
+class BluetoothRemoteGattServiceBlueZ
     : public device::BluetoothGattService,
       public bluez::BluetoothGattServiceClient::Observer,
       public bluez::BluetoothGattCharacteristicClient::Observer {
@@ -67,42 +68,42 @@
       const std::string error_name);
 
   // Returns the adapter associated with this service.
-  BluetoothAdapterChromeOS* GetAdapter() const;
+  BluetoothAdapterBlueZ* GetAdapter() const;
 
   // Notifies its observers that the GATT service has changed. This is mainly
-  // used by BluetoothRemoteGattCharacteristicChromeOS instances to notify
+  // used by BluetoothRemoteGattCharacteristicBlueZ instances to notify
   // service observers when characteristic descriptors get added and removed.
   void NotifyServiceChanged();
 
   // Notifies its observers that a descriptor |descriptor| belonging to
   // characteristic |characteristic| has been added or removed. This is used
-  // by BluetoothRemoteGattCharacteristicChromeOS instances to notify service
+  // by BluetoothRemoteGattCharacteristicBlueZ instances to notify service
   // observers when characteristic descriptors get added and removed. If |added|
   // is true, an "Added" event will be sent. Otherwise, a "Removed" event will
   // be sent.
   void NotifyDescriptorAddedOrRemoved(
-      BluetoothRemoteGattCharacteristicChromeOS* characteristic,
-      BluetoothRemoteGattDescriptorChromeOS* descriptor,
+      BluetoothRemoteGattCharacteristicBlueZ* characteristic,
+      BluetoothRemoteGattDescriptorBlueZ* descriptor,
       bool added);
 
   // Notifies its observers that the value of a descriptor has changed. Called
-  // by BluetoothRemoteGattCharacteristicChromeOS instances to notify service
+  // by BluetoothRemoteGattCharacteristicBlueZ instances to notify service
   // observers.
   void NotifyDescriptorValueChanged(
-      BluetoothRemoteGattCharacteristicChromeOS* characteristic,
-      BluetoothRemoteGattDescriptorChromeOS* descriptor,
+      BluetoothRemoteGattCharacteristicBlueZ* characteristic,
+      BluetoothRemoteGattDescriptorBlueZ* descriptor,
       const std::vector<uint8>& value);
 
  private:
-  friend class BluetoothDeviceChromeOS;
+  friend class BluetoothDeviceBlueZ;
 
-  typedef std::map<dbus::ObjectPath, BluetoothRemoteGattCharacteristicChromeOS*>
+  typedef std::map<dbus::ObjectPath, BluetoothRemoteGattCharacteristicBlueZ*>
       CharacteristicMap;
 
-  BluetoothRemoteGattServiceChromeOS(BluetoothAdapterChromeOS* adapter,
-                                     BluetoothDeviceChromeOS* device,
-                                     const dbus::ObjectPath& object_path);
-  ~BluetoothRemoteGattServiceChromeOS() override;
+  BluetoothRemoteGattServiceBlueZ(BluetoothAdapterBlueZ* adapter,
+                                  BluetoothDeviceBlueZ* device,
+                                  const dbus::ObjectPath& object_path);
+  ~BluetoothRemoteGattServiceBlueZ() override;
 
   // bluez::BluetoothGattServiceClient::Observer override.
   void GattServicePropertyChanged(const dbus::ObjectPath& object_path,
@@ -120,11 +121,11 @@
 
   // The adapter associated with this service. It's ok to store a raw pointer
   // here since |adapter_| indirectly owns this instance.
-  BluetoothAdapterChromeOS* adapter_;
+  BluetoothAdapterBlueZ* adapter_;
 
   // The device this GATT service belongs to. It's ok to store a raw pointer
   // here since |device_| owns this instance.
-  BluetoothDeviceChromeOS* device_;
+  BluetoothDeviceBlueZ* device_;
 
   // Mapping from GATT characteristic object paths to characteristic objects.
   // owned by this service. Since the Chrome OS implementation uses object
@@ -138,11 +139,11 @@
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothRemoteGattServiceChromeOS> weak_ptr_factory_;
+  base::WeakPtrFactory<BluetoothRemoteGattServiceBlueZ> weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_socket_chromeos.cc b/device/bluetooth/bluetooth_socket_bluez.cc
similarity index 74%
rename from device/bluetooth/bluetooth_socket_chromeos.cc
rename to device/bluetooth/bluetooth_socket_bluez.cc
index b3e357d0..46269c9 100644
--- a/device/bluetooth/bluetooth_socket_chromeos.cc
+++ b/device/bluetooth/bluetooth_socket_bluez.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/bluetooth/bluetooth_socket_chromeos.h"
+#include "device/bluetooth/bluetooth_socket_bluez.h"
 
 #include <queue>
 #include <string>
@@ -24,10 +24,10 @@
 #include "dbus/file_descriptor.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_adapter.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
-#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
+#include "device/bluetooth/bluetooth_adapter_profile_bluez.h"
 #include "device/bluetooth/bluetooth_device.h"
-#include "device/bluetooth/bluetooth_device_chromeos.h"
+#include "device/bluetooth/bluetooth_device_bluez.h"
 #include "device/bluetooth/bluetooth_socket.h"
 #include "device/bluetooth/bluetooth_socket_net.h"
 #include "device/bluetooth/bluetooth_socket_thread.h"
@@ -52,36 +52,33 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
 // static
-scoped_refptr<BluetoothSocketChromeOS>
-BluetoothSocketChromeOS::CreateBluetoothSocket(
+scoped_refptr<BluetoothSocketBlueZ> BluetoothSocketBlueZ::CreateBluetoothSocket(
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
     scoped_refptr<BluetoothSocketThread> socket_thread) {
   DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
 
   return make_scoped_refptr(
-      new BluetoothSocketChromeOS(ui_task_runner, socket_thread));
+      new BluetoothSocketBlueZ(ui_task_runner, socket_thread));
 }
 
-BluetoothSocketChromeOS::AcceptRequest::AcceptRequest() {}
+BluetoothSocketBlueZ::AcceptRequest::AcceptRequest() {}
 
-BluetoothSocketChromeOS::AcceptRequest::~AcceptRequest() {}
+BluetoothSocketBlueZ::AcceptRequest::~AcceptRequest() {}
 
-BluetoothSocketChromeOS::ConnectionRequest::ConnectionRequest()
-    : accepting(false),
-      cancelled(false) {}
+BluetoothSocketBlueZ::ConnectionRequest::ConnectionRequest()
+    : accepting(false), cancelled(false) {}
 
-BluetoothSocketChromeOS::ConnectionRequest::~ConnectionRequest() {}
+BluetoothSocketBlueZ::ConnectionRequest::~ConnectionRequest() {}
 
-BluetoothSocketChromeOS::BluetoothSocketChromeOS(
+BluetoothSocketBlueZ::BluetoothSocketBlueZ(
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
     scoped_refptr<BluetoothSocketThread> socket_thread)
-    : BluetoothSocketNet(ui_task_runner, socket_thread), profile_(nullptr) {
-}
+    : BluetoothSocketNet(ui_task_runner, socket_thread), profile_(nullptr) {}
 
-BluetoothSocketChromeOS::~BluetoothSocketChromeOS() {
+BluetoothSocketBlueZ::~BluetoothSocketBlueZ() {
   DCHECK(!profile_);
 
   if (adapter_.get()) {
@@ -90,8 +87,8 @@
   }
 }
 
-void BluetoothSocketChromeOS::Connect(
-    const BluetoothDeviceChromeOS* device,
+void BluetoothSocketBlueZ::Connect(
+    const BluetoothDeviceBlueZ* device,
     const BluetoothUUID& uuid,
     SecurityLevel security_level,
     const base::Closure& success_callback,
@@ -116,7 +113,7 @@
   RegisterProfile(device->adapter(), success_callback, error_callback);
 }
 
-void BluetoothSocketChromeOS::Listen(
+void BluetoothSocketBlueZ::Listen(
     scoped_refptr<BluetoothAdapter> adapter,
     SocketType socket_type,
     const BluetoothUUID& uuid,
@@ -152,11 +149,11 @@
       NOTREACHED();
   }
 
-  RegisterProfile(static_cast<BluetoothAdapterChromeOS*>(adapter.get()),
+  RegisterProfile(static_cast<BluetoothAdapterBlueZ*>(adapter.get()),
                   success_callback, error_callback);
 }
 
-void BluetoothSocketChromeOS::Close() {
+void BluetoothSocketBlueZ::Close() {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
   if (profile_)
@@ -178,7 +175,7 @@
   }
 }
 
-void BluetoothSocketChromeOS::Disconnect(const base::Closure& callback) {
+void BluetoothSocketBlueZ::Disconnect(const base::Closure& callback) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
   if (profile_)
@@ -192,7 +189,7 @@
   }
 }
 
-void BluetoothSocketChromeOS::Accept(
+void BluetoothSocketBlueZ::Accept(
     const AcceptCompletionCallback& success_callback,
     const ErrorCompletionCallback& error_callback) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
@@ -217,8 +214,8 @@
   }
 }
 
-void BluetoothSocketChromeOS::RegisterProfile(
-    BluetoothAdapterChromeOS* adapter,
+void BluetoothSocketBlueZ::RegisterProfile(
+    BluetoothAdapterBlueZ* adapter,
     const base::Closure& success_callback,
     const ErrorCompletionCallback& error_callback) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
@@ -238,18 +235,17 @@
   VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value()
           << ": Acquiring profile.";
 
-  adapter->UseProfile(
-      uuid_, device_path_, *options_, this,
-      base::Bind(&BluetoothSocketChromeOS::OnRegisterProfile, this,
-                 success_callback, error_callback),
-      base::Bind(&BluetoothSocketChromeOS::OnRegisterProfileError, this,
-                 error_callback));
+  adapter->UseProfile(uuid_, device_path_, *options_, this,
+                      base::Bind(&BluetoothSocketBlueZ::OnRegisterProfile, this,
+                                 success_callback, error_callback),
+                      base::Bind(&BluetoothSocketBlueZ::OnRegisterProfileError,
+                                 this, error_callback));
 }
 
-void BluetoothSocketChromeOS::OnRegisterProfile(
+void BluetoothSocketBlueZ::OnRegisterProfile(
     const base::Closure& success_callback,
     const ErrorCompletionCallback& error_callback,
-    BluetoothAdapterProfileChromeOS* profile) {
+    BluetoothAdapterProfileBlueZ* profile) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
   DCHECK(!profile_);
 
@@ -266,13 +262,13 @@
 
   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile(
       device_path_, uuid_.canonical_value(),
-      base::Bind(&BluetoothSocketChromeOS::OnConnectProfile, this,
+      base::Bind(&BluetoothSocketBlueZ::OnConnectProfile, this,
                  success_callback),
-      base::Bind(&BluetoothSocketChromeOS::OnConnectProfileError, this,
+      base::Bind(&BluetoothSocketBlueZ::OnConnectProfileError, this,
                  error_callback));
 }
 
-void BluetoothSocketChromeOS::OnRegisterProfileError(
+void BluetoothSocketBlueZ::OnRegisterProfileError(
     const ErrorCompletionCallback& error_callback,
     const std::string& error_message) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
@@ -282,7 +278,7 @@
   error_callback.Run(error_message);
 }
 
-void BluetoothSocketChromeOS::OnConnectProfile(
+void BluetoothSocketBlueZ::OnConnectProfile(
     const base::Closure& success_callback) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
   DCHECK(profile_);
@@ -292,7 +288,7 @@
   success_callback.Run();
 }
 
-void BluetoothSocketChromeOS::OnConnectProfileError(
+void BluetoothSocketBlueZ::OnConnectProfileError(
     const ErrorCompletionCallback& error_callback,
     const std::string& error_name,
     const std::string& error_message) {
@@ -306,8 +302,8 @@
   error_callback.Run(error_message);
 }
 
-void BluetoothSocketChromeOS::AdapterPresentChanged(BluetoothAdapter* adapter,
-                                                    bool present) {
+void BluetoothSocketBlueZ::AdapterPresentChanged(BluetoothAdapter* adapter,
+                                                 bool present) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
   if (!present) {
@@ -321,15 +317,14 @@
   VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value()
           << ": Acquiring profile.";
 
-  static_cast<BluetoothAdapterChromeOS*>(adapter)->UseProfile(
+  static_cast<BluetoothAdapterBlueZ*>(adapter)->UseProfile(
       uuid_, device_path_, *options_, this,
-      base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfile, this),
-      base::Bind(&BluetoothSocketChromeOS::OnInternalRegisterProfileError,
-                 this));
+      base::Bind(&BluetoothSocketBlueZ::OnInternalRegisterProfile, this),
+      base::Bind(&BluetoothSocketBlueZ::OnInternalRegisterProfileError, this));
 }
 
-void BluetoothSocketChromeOS::OnInternalRegisterProfile(
-    BluetoothAdapterProfileChromeOS* profile) {
+void BluetoothSocketBlueZ::OnInternalRegisterProfile(
+    BluetoothAdapterProfileBlueZ* profile) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
   DCHECK(!profile_);
 
@@ -338,21 +333,21 @@
   VLOG(1) << uuid_.canonical_value() << ": Profile re-registered";
 }
 
-void BluetoothSocketChromeOS::OnInternalRegisterProfileError(
+void BluetoothSocketBlueZ::OnInternalRegisterProfileError(
     const std::string& error_message) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
   LOG(WARNING) << "Failed to re-register profile: " << error_message;
 }
 
-void BluetoothSocketChromeOS::Released() {
+void BluetoothSocketBlueZ::Released() {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
   DCHECK(profile_);
 
   VLOG(1) << profile_->object_path().value() << ": Release";
 }
 
-void BluetoothSocketChromeOS::NewConnection(
+void BluetoothSocketBlueZ::NewConnection(
     const dbus::ObjectPath& device_path,
     scoped_ptr<dbus::FileDescriptor> fd,
     const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
@@ -367,13 +362,8 @@
 
     socket_thread()->task_runner()->PostTask(
         FROM_HERE,
-        base::Bind(
-            &BluetoothSocketChromeOS::DoNewConnection,
-            this,
-            device_path_,
-            base::Passed(&fd),
-            options,
-            callback));
+        base::Bind(&BluetoothSocketBlueZ::DoNewConnection, this, device_path_,
+                   base::Passed(&fd), options, callback));
   } else {
     linked_ptr<ConnectionRequest> request(new ConnectionRequest());
     request->device_path = device_path;
@@ -389,7 +379,7 @@
   }
 }
 
-void BluetoothSocketChromeOS::RequestDisconnection(
+void BluetoothSocketBlueZ::RequestDisconnection(
     const dbus::ObjectPath& device_path,
     const ConfirmationCallback& callback) {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
@@ -399,7 +389,7 @@
   callback.Run(SUCCESS);
 }
 
-void BluetoothSocketChromeOS::Cancel() {
+void BluetoothSocketBlueZ::Cancel() {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
   DCHECK(profile_);
 
@@ -418,7 +408,7 @@
   }
 }
 
-void BluetoothSocketChromeOS::AcceptConnectionRequest() {
+void BluetoothSocketBlueZ::AcceptConnectionRequest() {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
   DCHECK(accept_request_.get());
   DCHECK(connection_request_queue_.size() >= 1);
@@ -430,14 +420,14 @@
   linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
   request->accepting = true;
 
-  BluetoothDeviceChromeOS* device =
-      static_cast<BluetoothAdapterChromeOS*>(adapter_.get())->
-          GetDeviceWithPath(request->device_path);
+  BluetoothDeviceBlueZ* device =
+      static_cast<BluetoothAdapterBlueZ*>(adapter_.get())
+          ->GetDeviceWithPath(request->device_path);
   DCHECK(device);
 
-  scoped_refptr<BluetoothSocketChromeOS> client_socket =
-      BluetoothSocketChromeOS::CreateBluetoothSocket(
-          ui_task_runner(), socket_thread());
+  scoped_refptr<BluetoothSocketBlueZ> client_socket =
+      BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner(),
+                                                  socket_thread());
 
   client_socket->device_address_ = device->GetAddress();
   client_socket->device_path_ = request->device_path;
@@ -445,19 +435,14 @@
 
   socket_thread()->task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(
-          &BluetoothSocketChromeOS::DoNewConnection,
-          client_socket,
-          request->device_path,
-          base::Passed(&request->fd),
-          request->options,
-          base::Bind(&BluetoothSocketChromeOS::OnNewConnection,
-                     this,
-                     client_socket,
-                     request->callback)));
+      base::Bind(&BluetoothSocketBlueZ::DoNewConnection, client_socket,
+                 request->device_path, base::Passed(&request->fd),
+                 request->options,
+                 base::Bind(&BluetoothSocketBlueZ::OnNewConnection, this,
+                            client_socket, request->callback)));
 }
 
-void BluetoothSocketChromeOS::DoNewConnection(
+void BluetoothSocketBlueZ::DoNewConnection(
     const dbus::ObjectPath& device_path,
     scoped_ptr<dbus::FileDescriptor> fd,
     const bluez::BluetoothProfileServiceProvider::Delegate::Options& options,
@@ -470,15 +455,15 @@
   if (!fd->is_valid()) {
     LOG(WARNING) << uuid_.canonical_value() << " :" << fd->value()
                  << ": Invalid file descriptor received from Bluetooth Daemon.";
-    ui_task_runner()->PostTask(FROM_HERE,
-                               base::Bind(callback, REJECTED));;
+    ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED));
+    ;
     return;
   }
 
   if (tcp_socket()) {
     LOG(WARNING) << uuid_.canonical_value() << ": Already connected";
-    ui_task_runner()->PostTask(FROM_HERE,
-                               base::Bind(callback, REJECTED));;
+    ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED));
+    ;
     return;
   }
 
@@ -486,24 +471,24 @@
 
   // Note: We don't have a meaningful |IPEndPoint|, but that is ok since the
   // TCPSocket implementation does not actually require one.
-  int net_result = tcp_socket()->AdoptConnectedSocket(fd->value(),
-                                                      net::IPEndPoint());
+  int net_result =
+      tcp_socket()->AdoptConnectedSocket(fd->value(), net::IPEndPoint());
   if (net_result != net::OK) {
     LOG(WARNING) << uuid_.canonical_value() << ": Error adopting socket: "
                  << std::string(net::ErrorToString(net_result));
-    ui_task_runner()->PostTask(FROM_HERE,
-                               base::Bind(callback, REJECTED));;
+    ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, REJECTED));
+    ;
     return;
   }
 
   VLOG(2) << uuid_.canonical_value()
           << ": Taking descriptor, confirming success.";
   fd->TakeValue();
-  ui_task_runner()->PostTask(FROM_HERE,
-                             base::Bind(callback, SUCCESS));;
+  ui_task_runner()->PostTask(FROM_HERE, base::Bind(callback, SUCCESS));
+  ;
 }
 
-void BluetoothSocketChromeOS::OnNewConnection(
+void BluetoothSocketBlueZ::OnNewConnection(
     scoped_refptr<BluetoothSocket> socket,
     const ConfirmationCallback& callback,
     Status status) {
@@ -513,9 +498,9 @@
 
   linked_ptr<ConnectionRequest> request = connection_request_queue_.front();
   if (status == SUCCESS && !request->cancelled) {
-    BluetoothDeviceChromeOS* device =
-        static_cast<BluetoothAdapterChromeOS*>(adapter_.get())->
-            GetDeviceWithPath(request->device_path);
+    BluetoothDeviceBlueZ* device =
+        static_cast<BluetoothAdapterBlueZ*>(adapter_.get())
+            ->GetDeviceWithPath(request->device_path);
     DCHECK(device);
 
     accept_request_->success_callback.Run(device, socket);
@@ -529,7 +514,7 @@
   callback.Run(status);
 }
 
-void BluetoothSocketChromeOS::DoCloseListening() {
+void BluetoothSocketBlueZ::DoCloseListening() {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
   if (accept_request_) {
@@ -545,15 +530,15 @@
   }
 }
 
-void BluetoothSocketChromeOS::UnregisterProfile() {
+void BluetoothSocketBlueZ::UnregisterProfile() {
   DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
   DCHECK(profile_);
 
   VLOG(1) << profile_->object_path().value() << ": Release profile";
 
-  static_cast<BluetoothAdapterChromeOS*>(adapter_.get())
+  static_cast<BluetoothAdapterBlueZ*>(adapter_.get())
       ->ReleaseProfile(device_path_, profile_);
   profile_ = nullptr;
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_socket_chromeos.h b/device/bluetooth/bluetooth_socket_bluez.h
similarity index 86%
rename from device/bluetooth/bluetooth_socket_chromeos.h
rename to device/bluetooth/bluetooth_socket_bluez.h
index a1c76ee2..b1870ab 100644
--- a/device/bluetooth/bluetooth_socket_chromeos.h
+++ b/device/bluetooth/bluetooth_socket_bluez.h
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_BLUEZ_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_BLUEZ_H_
 
 #include <queue>
 #include <string>
 
+#include "base/macros.h"
 #include "base/memory/linked_ptr.h"
 #include "base/memory/scoped_ptr.h"
 #include "dbus/object_path.h"
@@ -23,27 +24,24 @@
 class FileDescriptor;
 }  // namespace dbus
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothDeviceChromeOS;
-class BluetoothAdapterChromeOS;
-class BluetoothAdapterProfileChromeOS;
+class BluetoothDeviceBlueZ;
+class BluetoothAdapterBlueZ;
+class BluetoothAdapterProfileBlueZ;
 
-// The BluetoothSocketChromeOS class implements BluetoothSocket for the
+// The BluetoothSocketBlueZ class implements BluetoothSocket for the
 // Chrome OS platform.
 //
 // This class is not thread-safe, but is only called from the UI thread.
-class DEVICE_BLUETOOTH_EXPORT BluetoothSocketChromeOS
+class DEVICE_BLUETOOTH_EXPORT BluetoothSocketBlueZ
     : public device::BluetoothSocketNet,
       public device::BluetoothAdapter::Observer,
       public bluez::BluetoothProfileServiceProvider::Delegate {
  public:
-  enum SecurityLevel {
-    SECURITY_LEVEL_LOW,
-    SECURITY_LEVEL_MEDIUM
-  };
+  enum SecurityLevel { SECURITY_LEVEL_LOW, SECURITY_LEVEL_MEDIUM };
 
-  static scoped_refptr<BluetoothSocketChromeOS> CreateBluetoothSocket(
+  static scoped_refptr<BluetoothSocketBlueZ> CreateBluetoothSocket(
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
       scoped_refptr<device::BluetoothSocketThread> socket_thread);
 
@@ -52,7 +50,7 @@
   // discovery. On a successful connection the socket properties will be updated
   // and |success_callback| called. On failure |error_callback| will be called
   // with a message explaining the cause of the failure.
-  virtual void Connect(const BluetoothDeviceChromeOS* device,
+  virtual void Connect(const BluetoothDeviceBlueZ* device,
                        const device::BluetoothUUID& uuid,
                        SecurityLevel security_level,
                        const base::Closure& success_callback,
@@ -80,20 +78,20 @@
               const ErrorCompletionCallback& error_callback) override;
 
  protected:
-  ~BluetoothSocketChromeOS() override;
+  ~BluetoothSocketBlueZ() override;
 
  private:
-  BluetoothSocketChromeOS(
+  BluetoothSocketBlueZ(
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
       scoped_refptr<device::BluetoothSocketThread> socket_thread);
 
   // Register the underlying profile client object with the Bluetooth Daemon.
-  void RegisterProfile(BluetoothAdapterChromeOS* adapter,
+  void RegisterProfile(BluetoothAdapterBlueZ* adapter,
                        const base::Closure& success_callback,
                        const ErrorCompletionCallback& error_callback);
   void OnRegisterProfile(const base::Closure& success_callback,
                          const ErrorCompletionCallback& error_callback,
-                         BluetoothAdapterProfileChromeOS* profile);
+                         BluetoothAdapterProfileBlueZ* profile);
   void OnRegisterProfileError(const ErrorCompletionCallback& error_callback,
                               const std::string& error_message);
 
@@ -109,7 +107,7 @@
 
   // Called by dbus:: on completion of the RegisterProfile() method call
   // triggered as a result of the adapter becoming present again.
-  void OnInternalRegisterProfile(BluetoothAdapterProfileChromeOS* profile);
+  void OnInternalRegisterProfile(BluetoothAdapterProfileBlueZ* profile);
   void OnInternalRegisterProfileError(const std::string& error_message);
 
   // bluez::BluetoothProfileServiceProvider::Delegate:
@@ -169,7 +167,7 @@
   scoped_ptr<bluez::BluetoothProfileManagerClient::Options> options_;
 
   // The profile registered with the adapter for this socket.
-  BluetoothAdapterProfileChromeOS* profile_;
+  BluetoothAdapterProfileBlueZ* profile_;
 
   // Pending request to an Accept() call.
   struct AcceptRequest {
@@ -193,11 +191,11 @@
     bool accepting;
     bool cancelled;
   };
-  std::queue<linked_ptr<ConnectionRequest> > connection_request_queue_;
+  std::queue<linked_ptr<ConnectionRequest>> connection_request_queue_;
 
-  DISALLOW_COPY_AND_ASSIGN(BluetoothSocketChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(BluetoothSocketBlueZ);
 };
 
-}  // namespace chromeos
+}  // namespace bluez
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_BLUEZ_H_
diff --git a/device/bluetooth/bluetooth_socket_chromeos_unittest.cc b/device/bluetooth/bluetooth_socket_bluez_unittest.cc
similarity index 81%
rename from device/bluetooth/bluetooth_socket_chromeos_unittest.cc
rename to device/bluetooth/bluetooth_socket_bluez_unittest.cc
index b306008b..171d77d 100644
--- a/device/bluetooth/bluetooth_socket_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_socket_bluez_unittest.cc
@@ -6,12 +6,12 @@
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
 #include "device/bluetooth/bluetooth_adapter.h"
-#include "device/bluetooth/bluetooth_adapter_chromeos.h"
+#include "device/bluetooth/bluetooth_adapter_bluez.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_device.h"
-#include "device/bluetooth/bluetooth_device_chromeos.h"
+#include "device/bluetooth/bluetooth_device_bluez.h"
 #include "device/bluetooth/bluetooth_socket.h"
-#include "device/bluetooth/bluetooth_socket_chromeos.h"
+#include "device/bluetooth/bluetooth_socket_bluez.h"
 #include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
@@ -39,11 +39,11 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace bluez {
 
-class BluetoothSocketChromeOSTest : public testing::Test {
+class BluetoothSocketBlueZTest : public testing::Test {
  public:
-  BluetoothSocketChromeOSTest()
+  BluetoothSocketBlueZTest()
       : success_callback_count_(0),
         error_callback_count_(0),
         last_bytes_sent_(0),
@@ -76,18 +76,15 @@
     BluetoothSocketThread::Get();
 
     // Grab a pointer to the adapter.
-    device::BluetoothAdapterFactory::GetAdapter(
-        base::Bind(&BluetoothSocketChromeOSTest::AdapterCallback,
-                   base::Unretained(this)));
+    device::BluetoothAdapterFactory::GetAdapter(base::Bind(
+        &BluetoothSocketBlueZTest::AdapterCallback, base::Unretained(this)));
     ASSERT_TRUE(adapter_.get() != nullptr);
     ASSERT_TRUE(adapter_->IsInitialized());
     ASSERT_TRUE(adapter_->IsPresent());
 
     // Turn on the adapter.
-    adapter_->SetPowered(
-        true,
-        base::Bind(&base::DoNothing),
-        base::Bind(&base::DoNothing));
+    adapter_->SetPowered(true, base::Bind(&base::DoNothing),
+                         base::Bind(&base::DoNothing));
     ASSERT_TRUE(adapter_->IsPowered());
   }
 
@@ -163,9 +160,7 @@
     message_loop_.QuitWhenIdle();
   }
 
-  void ImmediateSuccessCallback() {
-    ++success_callback_count_;
-  }
+  void ImmediateSuccessCallback() { ++success_callback_count_; }
 
  protected:
   base::MessageLoop message_loop_;
@@ -184,16 +179,16 @@
   const BluetoothDevice* last_device_;
 };
 
-TEST_F(BluetoothSocketChromeOSTest, Connect) {
+TEST_F(BluetoothSocketBlueZTest, Connect) {
   BluetoothDevice* device = adapter_->GetDevice(
       bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
 
   device->ConnectToService(
       BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
-      base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ConnectToServiceSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
   message_loop_.Run();
 
@@ -212,9 +207,9 @@
       new net::StringIOBuffer("test"));
 
   socket->Send(write_buffer.get(), write_buffer->size(),
-               base::Bind(&BluetoothSocketChromeOSTest::SendSuccessCallback,
+               base::Bind(&BluetoothSocketBlueZTest::SendSuccessCallback,
                           base::Unretained(this)),
-               base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+               base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                           base::Unretained(this)));
   message_loop_.Run();
 
@@ -227,12 +222,11 @@
 
   // Receive data from the socket, and fetch the buffer from the callback; since
   // the fake is an echo server, we expect to receive what we wrote.
-  socket->Receive(
-      4096,
-      base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback,
-                 base::Unretained(this)));
+  socket->Receive(4096,
+                  base::Bind(&BluetoothSocketBlueZTest::ReceiveSuccessCallback,
+                             base::Unretained(this)),
+                  base::Bind(&BluetoothSocketBlueZTest::ReceiveErrorCallback,
+                             base::Unretained(this)));
   message_loop_.Run();
 
   EXPECT_EQ(1U, success_callback_count_);
@@ -253,12 +247,11 @@
 
   // Receive data again; the socket will have been closed, this should cause a
   // disconnected error to be returned via the error callback.
-  socket->Receive(
-      4096,
-      base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback,
-                 base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback,
-                 base::Unretained(this)));
+  socket->Receive(4096,
+                  base::Bind(&BluetoothSocketBlueZTest::ReceiveSuccessCallback,
+                             base::Unretained(this)),
+                  base::Bind(&BluetoothSocketBlueZTest::ReceiveErrorCallback,
+                             base::Unretained(this)));
   message_loop_.Run();
 
   EXPECT_EQ(0U, success_callback_count_);
@@ -274,9 +267,9 @@
   write_buffer = new net::StringIOBuffer("second test");
 
   socket->Send(write_buffer.get(), write_buffer->size(),
-               base::Bind(&BluetoothSocketChromeOSTest::SendSuccessCallback,
+               base::Bind(&BluetoothSocketBlueZTest::SendSuccessCallback,
                           base::Unretained(this)),
-               base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+               base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                           base::Unretained(this)));
   message_loop_.Run();
 
@@ -288,20 +281,20 @@
   error_callback_count_ = 0;
 
   // Close our end of the socket.
-  socket->Disconnect(base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
+  socket->Disconnect(base::Bind(&BluetoothSocketBlueZTest::SuccessCallback,
                                 base::Unretained(this)));
 
   message_loop_.Run();
   EXPECT_EQ(1U, success_callback_count_);
 }
 
-TEST_F(BluetoothSocketChromeOSTest, Listen) {
+TEST_F(BluetoothSocketBlueZTest, Listen) {
   adapter_->CreateRfcommService(
       BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
-      base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.Run();
@@ -329,16 +322,16 @@
       bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
   ASSERT_TRUE(device != nullptr);
   fake_bluetooth_device_client->ConnectProfile(
-      static_cast<BluetoothDeviceChromeOS*>(device)->object_path(),
+      static_cast<BluetoothDeviceBlueZ*>(device)->object_path(),
       bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
       base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback));
 
   message_loop_.RunUntilIdle();
 
   server_socket->Accept(
-      base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::AcceptSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.Run();
@@ -354,9 +347,8 @@
   error_callback_count_ = 0;
 
   // Close our end of the client socket.
-  client_socket->Disconnect(
-      base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
-                 base::Unretained(this)));
+  client_socket->Disconnect(base::Bind(
+      &BluetoothSocketBlueZTest::SuccessCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -368,15 +360,15 @@
   // Run a second connection test, this time calling Accept() before the
   // incoming connection comes in.
   server_socket->Accept(
-      base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::AcceptSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
 
   fake_bluetooth_device_client->ConnectProfile(
-      static_cast<BluetoothDeviceChromeOS*>(device)->object_path(),
+      static_cast<BluetoothDeviceBlueZ*>(device)->object_path(),
       bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
       base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback));
 
@@ -393,9 +385,8 @@
   error_callback_count_ = 0;
 
   // Close our end of the client socket.
-  client_socket->Disconnect(
-      base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
-                 base::Unretained(this)));
+  client_socket->Disconnect(base::Bind(
+      &BluetoothSocketBlueZTest::SuccessCallback, base::Unretained(this)));
 
   message_loop_.Run();
 
@@ -406,7 +397,7 @@
 
   // Now close the server socket.
   server_socket->Disconnect(
-      base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ImmediateSuccessCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -414,7 +405,7 @@
   EXPECT_EQ(1U, success_callback_count_);
 }
 
-TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) {
+TEST_F(BluetoothSocketBlueZTest, ListenBeforeAdapterStart) {
   // Start off with an invisible adapter, register the profile, then make
   // the adapter visible.
   bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
@@ -425,9 +416,9 @@
   adapter_->CreateRfcommService(
       BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
-      base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
   message_loop_.Run();
 
@@ -464,7 +455,7 @@
 
   // Cleanup the socket.
   socket->Disconnect(
-      base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ImmediateSuccessCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -472,7 +463,7 @@
   EXPECT_EQ(1U, success_callback_count_);
 }
 
-TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) {
+TEST_F(BluetoothSocketBlueZTest, ListenAcrossAdapterRestart) {
   // The fake adapter starts off visible by default.
   bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
       static_cast<bluez::FakeBluetoothAdapterClient*>(
@@ -481,9 +472,9 @@
   adapter_->CreateRfcommService(
       BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
-      base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
   message_loop_.Run();
 
@@ -526,7 +517,7 @@
 
   // Cleanup the socket.
   socket->Disconnect(
-      base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ImmediateSuccessCallback,
                  base::Unretained(this)));
 
   message_loop_.RunUntilIdle();
@@ -534,16 +525,16 @@
   EXPECT_EQ(1U, success_callback_count_);
 }
 
-TEST_F(BluetoothSocketChromeOSTest, PairedConnectFails) {
+TEST_F(BluetoothSocketBlueZTest, PairedConnectFails) {
   BluetoothDevice* device = adapter_->GetDevice(
       bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress);
   ASSERT_TRUE(device != nullptr);
 
   device->ConnectToService(
       BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
-      base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ConnectToServiceSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
   message_loop_.Run();
 
@@ -553,9 +544,9 @@
 
   device->ConnectToService(
       BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
-      base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ConnectToServiceSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
   message_loop_.Run();
 
@@ -564,13 +555,13 @@
   EXPECT_TRUE(last_socket_.get() == nullptr);
 }
 
-TEST_F(BluetoothSocketChromeOSTest, SocketListenTwice) {
+TEST_F(BluetoothSocketBlueZTest, SocketListenTwice) {
   adapter_->CreateRfcommService(
       BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
-      base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.Run();
@@ -584,9 +575,9 @@
   server_socket.swap(last_socket_);
 
   server_socket->Accept(
-      base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::AcceptSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
 
   server_socket->Close();
@@ -601,9 +592,9 @@
   adapter_->CreateRfcommService(
       BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
       BluetoothAdapter::ServiceOptions(),
-      base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
 
   message_loop_.Run();
@@ -616,9 +607,9 @@
   server_socket.swap(last_socket_);
 
   server_socket->Accept(
-      base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
+      base::Bind(&BluetoothSocketBlueZTest::AcceptSuccessCallback,
                  base::Unretained(this)),
-      base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
+      base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
                  base::Unretained(this)));
 
   server_socket->Close();
@@ -631,4 +622,4 @@
   EXPECT_EQ(2U, error_callback_count_);
 }
 
-}  // namespace chromeos
+}  // namespace bluez
diff --git a/device/bluetooth/bluetooth_socket_thread.h b/device/bluetooth/bluetooth_socket_thread.h
index 244640f..0c7b65c 100644
--- a/device/bluetooth/bluetooth_socket_thread.h
+++ b/device/bluetooth/bluetooth_socket_thread.h
@@ -17,7 +17,7 @@
 
 namespace device {
 
-// Thread abstraction used by |BluetoothSocketChromeOS| and |BluetoothSocketWin|
+// Thread abstraction used by |BluetoothSocketBlueZ| and |BluetoothSocketWin|
 // to perform IO operations on the underlying platform sockets. An instance of
 // this class can be shared by many active sockets.
 class DEVICE_BLUETOOTH_EXPORT BluetoothSocketThread
diff --git a/device/bluetooth/dbus/bluetooth_agent_service_provider.h b/device/bluetooth/dbus/bluetooth_agent_service_provider.h
index e31ef8f9..162cf7e 100644
--- a/device/bluetooth/dbus/bluetooth_agent_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_agent_service_provider.h
@@ -21,10 +21,10 @@
 //
 // Instantiate with a chosen D-Bus object path and delegate object, and pass
 // the D-Bus object path as the |agent_path| argument to the
-// chromeos::BluetoothAgentManagerClient::RegisterAgent() method.
+// bluez::BluetoothAgentManagerClient::RegisterAgent() method.
 //
 // After initiating the pairing process with a device, using the
-// chromeos::BluetoothDeviceClient::Pair() method, the Bluetooth daemon will
+// bluez::BluetoothDeviceClient::Pair() method, the Bluetooth daemon will
 // make calls to this agent object and they will be passed on to your Delegate
 // object for handling. Responses should be returned using the callbacks
 // supplied to those methods.
diff --git a/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc
index 29a4ce8..1d53d8a3 100644
--- a/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc
+++ b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc
@@ -9,7 +9,6 @@
 #include "base/command_line.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
-#include "chromeos/chromeos_switches.h"
 #include "device/bluetooth/dbus/bluetooth_adapter_client.h"
 #include "device/bluetooth/dbus/bluetooth_agent_manager_client.h"
 #include "device/bluetooth/dbus/bluetooth_device_client.h"
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
index 6000a52..d6229a3a 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
@@ -210,7 +210,7 @@
   }
 
  protected:
-  // chromeos::DBusClient override.
+  // bluez::DBusClient override.
   void Init(dbus::Bus* bus) override {
     object_manager_ = bus->GetObjectManager(
         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
index f3ba343c..d3f9e5f 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
@@ -159,7 +159,7 @@
   }
 
  protected:
-  // chromeos::DBusClient override.
+  // bluez::DBusClient override.
   void Init(dbus::Bus* bus) override {
     object_manager_ = bus->GetObjectManager(
         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
diff --git a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
index 7e471a5c..94f79f5 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
@@ -73,7 +73,7 @@
   }
 
  protected:
-  // chromeos::DBusClient override.
+  // bluez::DBusClient override.
   void Init(dbus::Bus* bus) override {
     DCHECK(bus);
     object_proxy_ = bus->GetObjectProxy(
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/bluetooth_gatt_service_client.cc
index dc3ef5a..b13e5fb4 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_service_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_client.cc
@@ -95,7 +95,7 @@
   }
 
  protected:
-  // chromeos::DBusClient override.
+  // bluez::DBusClient override.
   void Init(dbus::Bus* bus) override {
     object_manager_ = bus->GetObjectManager(
         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
index cedec1e1..ba101ca7 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
@@ -22,7 +22,7 @@
 // Instantiate with a chosen D-Bus object path (that conforms to the BlueZ GATT
 // service specification), service UUID, and the list of included services, and
 // pass the D-Bus object path as the |service_path| argument to the
-// chromeos::BluetoothGattManagerClient::RegisterService method. Make sure to
+// bluez::BluetoothGattManagerClient::RegisterService method. Make sure to
 // create characteristic and descriptor objects using the appropriate service
 // providers before registering a GATT service with the Bluetooth daemon.
 class DEVICE_BLUETOOTH_EXPORT BluetoothGattServiceServiceProvider {
diff --git a/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h
index d44c065..8a806cb3 100644
--- a/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h
@@ -22,7 +22,7 @@
 //
 // Instantiate with a chosen D-Bus object path and a delegate object, and pass
 // the D-Bus object path as |endpoint_path| argument to the
-// chromeos::BluetoothMediaClient::RegisterEndoint() method.
+// bluez::BluetoothMediaClient::RegisterEndoint() method.
 //
 // After initiating a connection between an audio source and an audio sink, the
 // Bluetooth daemon will make calls to this endpoint object and they will be
diff --git a/device/bluetooth/dbus/bluetooth_profile_service_provider.h b/device/bluetooth/dbus/bluetooth_profile_service_provider.h
index f2db22c7..109bcaf6 100644
--- a/device/bluetooth/dbus/bluetooth_profile_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_profile_service_provider.h
@@ -22,10 +22,10 @@
 //
 // Instantiate with a chosen D-Bus object path and delegate object, and pass
 // the D-Bus object path as the |agent_path| argument to the
-// chromeos::BluetoothProfileManagerClient::RegisterProfile() method.
+// bluez::BluetoothProfileManagerClient::RegisterProfile() method.
 //
 // When an incoming profile connection occurs, or after initiating a connection
-// using the chromeos::BluetoothDeviceClient::ConnectProfile() method, the
+// using the bluez::BluetoothDeviceClient::ConnectProfile() method, the
 // Bluetooth daemon will make calls to this profile object and they will be
 // passed on to your Delegate object for handling. Responses should be returned
 // using the callbacks supplied to those methods.
diff --git a/device/bluetooth/dbus/bluez_dbus_manager.h b/device/bluetooth/dbus/bluez_dbus_manager.h
index d87fadc..fe879c4 100644
--- a/device/bluetooth/dbus/bluez_dbus_manager.h
+++ b/device/bluetooth/dbus/bluez_dbus_manager.h
@@ -57,7 +57,7 @@
   // We explicitly initialize and shut down the global object, rather than
   // making it a Singleton, to ensure clean startup and shutdown.
   // This will initialize real or stub DBusClients depending on command-line
-  // arguments and whether this process runs in a ChromeOS environment.
+  // arguments and whether this process runs in a real or test environment.
   static void Initialize(dbus::Bus* bus, bool use_dbus_stub);
 
   // Returns a BluezDBusManagerSetter instance that allows tests to
diff --git a/device/bluetooth/dbus/dbus_thread_manager_linux.cc b/device/bluetooth/dbus/dbus_thread_manager_linux.cc
new file mode 100644
index 0000000..adffe9b
--- /dev/null
+++ b/device/bluetooth/dbus/dbus_thread_manager_linux.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/dbus/dbus_thread_manager_linux.h"
+
+#include "base/threading/thread.h"
+#include "dbus/bus.h"
+
+namespace bluez {
+
+static DBusThreadManagerLinux* g_linux_dbus_manager = NULL;
+
+DBusThreadManagerLinux::DBusThreadManagerLinux() {
+  base::Thread::Options thread_options;
+  thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
+  dbus_thread_.reset(new base::Thread("D-Bus thread"));
+  dbus_thread_->StartWithOptions(thread_options);
+
+  // Create the connection to the system bus.
+  dbus::Bus::Options system_bus_options;
+  system_bus_options.bus_type = dbus::Bus::SYSTEM;
+  system_bus_options.connection_type = dbus::Bus::PRIVATE;
+  system_bus_options.dbus_task_runner = dbus_thread_->task_runner();
+  system_bus_ = new dbus::Bus(system_bus_options);
+}
+
+DBusThreadManagerLinux::~DBusThreadManagerLinux() {
+  // Shut down the bus. During the browser shutdown, it's ok to shut down
+  // the bus synchronously.
+  if (system_bus_.get())
+    system_bus_->ShutdownOnDBusThreadAndBlock();
+
+  // Stop the D-Bus thread.
+  if (dbus_thread_)
+    dbus_thread_->Stop();
+
+  if (!g_linux_dbus_manager)
+    return;  // Called form Shutdown() or local test instance.
+
+  // There should never be both a global instance and a local instance.
+  CHECK(this == g_linux_dbus_manager);
+}
+
+dbus::Bus* DBusThreadManagerLinux::GetSystemBus() {
+  return system_bus_.get();
+}
+
+// static
+void DBusThreadManagerLinux::Initialize() {
+  CHECK(!g_linux_dbus_manager);
+  g_linux_dbus_manager = new DBusThreadManagerLinux();
+}
+
+// static
+void DBusThreadManagerLinux::Shutdown() {
+  // Ensure that we only shutdown LinuxDBusManager once.
+  CHECK(g_linux_dbus_manager);
+  DBusThreadManagerLinux* dbus_thread_manager = g_linux_dbus_manager;
+  g_linux_dbus_manager = NULL;
+  delete dbus_thread_manager;
+  VLOG(1) << "LinuxDBusManager Shutdown completed";
+}
+
+// static
+DBusThreadManagerLinux* DBusThreadManagerLinux::Get() {
+  CHECK(g_linux_dbus_manager)
+      << "LinuxDBusManager::Get() called before Initialize()";
+  return g_linux_dbus_manager;
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/dbus_thread_manager_linux.h b/device/bluetooth/dbus/dbus_thread_manager_linux.h
new file mode 100644
index 0000000..880a77cd
--- /dev/null
+++ b/device/bluetooth/dbus/dbus_thread_manager_linux.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_DBUS_DBUS_THREAD_MANAGER_LINUX_H_
+#define DEVICE_BLUETOOTH_DBUS_DBUS_THREAD_MANAGER_LINUX_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "device/bluetooth/bluetooth_export.h"
+
+namespace base {
+class Thread;
+}  // namespace base
+
+namespace dbus {
+class Bus;
+}  // namespace dbus
+
+namespace bluez {
+
+// LinuxDBusManager manages the D-Bus thread, the thread dedicated to
+// handling asynchronous D-Bus operations.
+class DEVICE_BLUETOOTH_EXPORT DBusThreadManagerLinux {
+ public:
+  // Sets the global instance. Must be called before any calls to Get().
+  // We explicitly initialize and shut down the global object, rather than
+  // making it a Singleton, to ensure clean startup and shutdown.
+  static void Initialize();
+
+  // Destroys the global instance.
+  static void Shutdown();
+
+  // Gets the global instance. Initialize() must be called first.
+  static DBusThreadManagerLinux* Get();
+
+  // Returns various D-Bus bus instances, owned by LinuxDBusManager.
+  dbus::Bus* GetSystemBus();
+
+ private:
+  explicit DBusThreadManagerLinux();
+  ~DBusThreadManagerLinux();
+
+  // Creates a global instance of LinuxDBusManager with the real
+  // implementations for all clients that are listed in |unstub_client_mask| and
+  // stub implementations for all clients that are not included. Cannot be
+  // called more than once.
+  static void CreateGlobalInstance();
+
+  scoped_ptr<base::Thread> dbus_thread_;
+  scoped_refptr<dbus::Bus> system_bus_;
+
+  DISALLOW_COPY_AND_ASSIGN(DBusThreadManagerLinux);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_DBUS_THREAD_MANAGER_LINUX_H_
diff --git a/device/bluetooth/dbus/fake_bluetooth_device_client.cc b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
index 83d31dd4..e6c137b 100644
--- a/device/bluetooth/dbus/fake_bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
@@ -1000,7 +1000,7 @@
 
   // Remove the Input interface if it exists. This should be called before the
   // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
-  // BluetoothDeviceChromeOS object, including the device_path referenced here.
+  // BluetoothDeviceBlueZ object, including the device_path referenced here.
   FakeBluetoothInputClient* fake_bluetooth_input_client =
       static_cast<FakeBluetoothInputClient*>(
           bluez::BluezDBusManager::Get()->GetBluetoothInputClient());
diff --git a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
index a38f749..bf3d8a0 100644
--- a/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
+++ b/device/bluetooth/test/android/java/src/org/chromium/device/bluetooth/Fakes.java
@@ -277,6 +277,7 @@
         final FakeBluetoothDevice mDevice;
         final ArrayList<Wrappers.BluetoothGattServiceWrapper> mServices;
         boolean mReadCharacteristicWillFailSynchronouslyOnce = false;
+        boolean mSetCharacteristicNotificationWillFailSynchronouslyOnce = false;
         boolean mWriteCharacteristicWillFailSynchronouslyOnce = false;
 
         public FakeBluetoothGatt(FakeBluetoothDevice device) {
@@ -312,6 +313,18 @@
         }
 
         @Override
+        boolean setCharacteristicNotification(
+                Wrappers.BluetoothGattCharacteristicWrapper characteristic, boolean enable) {
+            if (mSetCharacteristicNotificationWillFailSynchronouslyOnce) {
+                mSetCharacteristicNotificationWillFailSynchronouslyOnce = false;
+                return false;
+            }
+            nativeOnFakeBluetoothGattSetCharacteristicNotification(
+                    mDevice.mAdapter.mNativeBluetoothTestAndroid);
+            return true;
+        }
+
+        @Override
         boolean writeCharacteristic(Wrappers.BluetoothGattCharacteristicWrapper characteristic) {
             if (mWriteCharacteristicWillFailSynchronouslyOnce) {
                 mWriteCharacteristicWillFailSynchronouslyOnce = false;
@@ -424,6 +437,17 @@
 
         // Cause subsequent value reads of a characteristic to fail synchronously.
         @CalledByNative("FakeBluetoothGattCharacteristic")
+        private static void setCharacteristicNotificationWillFailSynchronouslyOnce(
+                ChromeBluetoothRemoteGattCharacteristic chromeCharacteristic) {
+            FakeBluetoothGattCharacteristic fakeCharacteristic =
+                    (FakeBluetoothGattCharacteristic) chromeCharacteristic.mCharacteristic;
+
+            fakeCharacteristic.mService.mDevice.mGatt
+                    .mSetCharacteristicNotificationWillFailSynchronouslyOnce = true;
+        }
+
+        // Cause subsequent value reads of a characteristic to fail synchronously.
+        @CalledByNative("FakeBluetoothGattCharacteristic")
         private static void setReadCharacteristicWillFailSynchronouslyOnce(
                 ChromeBluetoothRemoteGattCharacteristic chromeCharacteristic) {
             FakeBluetoothGattCharacteristic fakeCharacteristic =
@@ -477,22 +501,26 @@
     // ---------------------------------------------------------------------------------------------
     // BluetoothTestAndroid C++ methods declared for access from java:
 
-    // Binds to BluetoothAdapterAndroid::OnFakeBluetoothDeviceConnectGattCalled.
+    // Binds to BluetoothTestAndroid::OnFakeBluetoothDeviceConnectGattCalled.
     private static native void nativeOnFakeBluetoothDeviceConnectGattCalled(
             long nativeBluetoothTestAndroid);
 
-    // Binds to BluetoothAdapterAndroid::OnFakeBluetoothGattDisconnect.
+    // Binds to BluetoothTestAndroid::OnFakeBluetoothGattDisconnect.
     private static native void nativeOnFakeBluetoothGattDisconnect(long nativeBluetoothTestAndroid);
 
-    // Binds to BluetoothAdapterAndroid::OnFakeBluetoothGattDiscoverServices.
+    // Binds to BluetoothTestAndroid::OnFakeBluetoothGattDiscoverServices.
     private static native void nativeOnFakeBluetoothGattDiscoverServices(
             long nativeBluetoothTestAndroid);
 
-    // Binds to BluetoothAdapterAndroid::OnFakeBluetoothGattReadCharacteristic.
+    // Binds to BluetoothTestAndroid::OnFakeBluetoothGattSetCharacteristicNotification.
+    private static native void nativeOnFakeBluetoothGattSetCharacteristicNotification(
+            long nativeBluetoothTestAndroid);
+
+    // Binds to BluetoothTestAndroid::OnFakeBluetoothGattReadCharacteristic.
     private static native void nativeOnFakeBluetoothGattReadCharacteristic(
             long nativeBluetoothTestAndroid);
 
-    // Binds to BluetoothAdapterAndroid::OnFakeBluetoothGattWriteCharacteristic.
+    // Binds to BluetoothTestAndroid::OnFakeBluetoothGattWriteCharacteristic.
     private static native void nativeOnFakeBluetoothGattWriteCharacteristic(
             long nativeBluetoothTestAndroid, byte[] value);
 }
diff --git a/device/bluetooth/test/bluetooth_test.cc b/device/bluetooth/test/bluetooth_test.cc
index e35ee87cc..70d457f 100644
--- a/device/bluetooth/test/bluetooth_test.cc
+++ b/device/bluetooth/test/bluetooth_test.cc
@@ -64,6 +64,12 @@
   gatt_connections_.push_back(connection.release());
 }
 
+void BluetoothTestBase::NotifyCallback(
+    scoped_ptr<BluetoothGattNotifySession> notify_session) {
+  ++callback_count_;
+  notify_sessions_.push_back(notify_session.release());
+}
+
 void BluetoothTestBase::ReadValueCallback(const std::vector<uint8>& value) {
   ++callback_count_;
   last_read_value_ = value;
@@ -101,6 +107,12 @@
                     weak_factory_.GetWeakPtr());
 }
 
+BluetoothGattCharacteristic::NotifySessionCallback
+BluetoothTestBase::GetNotifyCallback() {
+  return base::Bind(&BluetoothTestBase::NotifyCallback,
+                    weak_factory_.GetWeakPtr());
+}
+
 BluetoothGattCharacteristic::ValueCallback
 BluetoothTestBase::GetReadValueCallback() {
   return base::Bind(&BluetoothTestBase::ReadValueCallback,
@@ -131,6 +143,7 @@
   gatt_connection_attempts_ = 0;
   gatt_disconnection_attempts_ = 0;
   gatt_discovery_attempts_ = 0;
+  gatt_notify_characteristic_attempts_ = 0;
   gatt_read_characteristic_attempts_ = 0;
   gatt_write_characteristic_attempts_ = 0;
 }
diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h
index 81de2b7..c4f8687 100644
--- a/device/bluetooth/test/bluetooth_test.h
+++ b/device/bluetooth/test/bluetooth_test.h
@@ -13,6 +13,7 @@
 #include "device/bluetooth/bluetooth_discovery_session.h"
 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
 #include "device/bluetooth/bluetooth_gatt_connection.h"
+#include "device/bluetooth/bluetooth_gatt_notify_session.h"
 #include "device/bluetooth/bluetooth_gatt_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -101,6 +102,15 @@
                                           const std::string& uuid,
                                           int properties) {}
 
+  // Simulates a Characteristic Set Notify success.
+  virtual void SimulateGattNotifySessionStarted(
+      BluetoothGattCharacteristic* characteristic) {}
+
+  // Simulates a Characteristic Set Notify operation failing synchronously once
+  // for an unknown reason.
+  virtual void SimulateGattCharacteristicSetNotifyWillFailSynchronouslyOnce(
+      BluetoothGattCharacteristic* characteristic) {}
+
   // Simulates a Characteristic Read operation succeeding, returning |value|.
   virtual void SimulateGattCharacteristicRead(
       BluetoothGattCharacteristic* characteristic,
@@ -137,6 +147,7 @@
   void Callback();
   void DiscoverySessionCallback(scoped_ptr<BluetoothDiscoverySession>);
   void GattConnectionCallback(scoped_ptr<BluetoothGattConnection>);
+  void NotifyCallback(scoped_ptr<BluetoothGattNotifySession>);
   void ReadValueCallback(const std::vector<uint8>& value);
   void ErrorCallback();
   void ConnectErrorCallback(enum BluetoothDevice::ConnectErrorCode);
@@ -146,6 +157,7 @@
   base::Closure GetCallback();
   BluetoothAdapter::DiscoverySessionCallback GetDiscoverySessionCallback();
   BluetoothDevice::GattConnectionCallback GetGattConnectionCallback();
+  BluetoothGattCharacteristic::NotifySessionCallback GetNotifyCallback();
   BluetoothGattCharacteristic::ValueCallback GetReadValueCallback();
   BluetoothAdapter::ErrorCallback GetErrorCallback();
   BluetoothDevice::ConnectErrorCallback GetConnectErrorCallback();
@@ -164,6 +176,7 @@
   ScopedVector<BluetoothGattConnection> gatt_connections_;
   enum BluetoothDevice::ConnectErrorCode last_connect_error_code_ =
       BluetoothDevice::ERROR_UNKNOWN;
+  ScopedVector<BluetoothGattNotifySession> notify_sessions_;
   std::vector<uint8> last_read_value_;
   std::vector<uint8> last_write_value_;
   BluetoothGattService::GattErrorCode last_gatt_error_code_;
@@ -172,6 +185,7 @@
   int gatt_connection_attempts_ = 0;
   int gatt_disconnection_attempts_ = 0;
   int gatt_discovery_attempts_ = 0;
+  int gatt_notify_characteristic_attempts_ = 0;
   int gatt_read_characteristic_attempts_ = 0;
   int gatt_write_characteristic_attempts_ = 0;
   base::WeakPtrFactory<BluetoothTestBase> weak_factory_;
diff --git a/device/bluetooth/test/bluetooth_test_android.cc b/device/bluetooth/test/bluetooth_test_android.cc
index 5cd0674..28514f7 100644
--- a/device/bluetooth/test/bluetooth_test_android.cc
+++ b/device/bluetooth/test/bluetooth_test_android.cc
@@ -10,6 +10,7 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/logging.h"
+#include "base/run_loop.h"
 #include "device/bluetooth/android/wrappers.h"
 #include "device/bluetooth/bluetooth_adapter_android.h"
 #include "device/bluetooth/bluetooth_device_android.h"
@@ -156,6 +157,25 @@
       base::android::ConvertUTF8ToJavaString(env, uuid).obj(), properties);
 }
 
+void BluetoothTestAndroid::SimulateGattNotifySessionStarted(
+    BluetoothGattCharacteristic* characteristic) {
+  // Android doesn't provide any sort of callback for when notifications have
+  // been enabled. So, just run the message loop to process the success
+  // callback.
+  base::RunLoop().RunUntilIdle();
+}
+
+void BluetoothTestAndroid::
+    SimulateGattCharacteristicSetNotifyWillFailSynchronouslyOnce(
+        BluetoothGattCharacteristic* characteristic) {
+  BluetoothRemoteGattCharacteristicAndroid* characteristic_android =
+      static_cast<BluetoothRemoteGattCharacteristicAndroid*>(characteristic);
+  JNIEnv* env = base::android::AttachCurrentThread();
+
+  Java_FakeBluetoothGattCharacteristic_setCharacteristicNotificationWillFailSynchronouslyOnce(
+      env, characteristic_android->GetJavaObject().obj());
+}
+
 void BluetoothTestAndroid::SimulateGattCharacteristicRead(
     BluetoothGattCharacteristic* characteristic,
     const std::vector<uint8>& value) {
@@ -241,6 +261,12 @@
   gatt_discovery_attempts_++;
 }
 
+void BluetoothTestAndroid::OnFakeBluetoothGattSetCharacteristicNotification(
+    JNIEnv* env,
+    jobject caller) {
+  gatt_notify_characteristic_attempts_++;
+}
+
 void BluetoothTestAndroid::OnFakeBluetoothGattReadCharacteristic(
     JNIEnv* env,
     jobject caller) {
diff --git a/device/bluetooth/test/bluetooth_test_android.h b/device/bluetooth/test/bluetooth_test_android.h
index 48939b37..0c2b35696 100644
--- a/device/bluetooth/test/bluetooth_test_android.h
+++ b/device/bluetooth/test/bluetooth_test_android.h
@@ -38,6 +38,10 @@
   void SimulateGattCharacteristic(BluetoothGattService* service,
                                   const std::string& uuid,
                                   int properties) override;
+  virtual void SimulateGattNotifySessionStarted(
+      BluetoothGattCharacteristic* characteristic) override;
+  virtual void SimulateGattCharacteristicSetNotifyWillFailSynchronouslyOnce(
+      BluetoothGattCharacteristic* characteristic) override;
   void SimulateGattCharacteristicRead(
       BluetoothGattCharacteristic* characteristic,
       const std::vector<uint8>& value) override;
@@ -63,10 +67,15 @@
   // Records that Java FakeBluetoothGatt discoverServices was called.
   void OnFakeBluetoothGattDiscoverServices(JNIEnv* env, jobject caller);
 
-  // Records that Java FakeBluetoothGatt discoverServices was called.
+  // Records that Java FakeBluetoothGatt setCharacteristicNotification was
+  // called.
+  void OnFakeBluetoothGattSetCharacteristicNotification(JNIEnv* env,
+                                                        jobject caller);
+
+  // Records that Java FakeBluetoothGatt readCharacteristic was called.
   void OnFakeBluetoothGattReadCharacteristic(JNIEnv* env, jobject caller);
 
-  // Records that Java FakeBluetoothGatt discoverServices was called.
+  // Records that Java FakeBluetoothGatt writeCharacteristic was called.
   void OnFakeBluetoothGattWriteCharacteristic(JNIEnv* env,
                                               jobject caller,
                                               jbyteArray value);
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.cc b/device/bluetooth/test/mock_bluetooth_adapter.cc
index 26ae68b..4b060e5 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.cc
+++ b/device/bluetooth/test/mock_bluetooth_adapter.cc
@@ -27,7 +27,7 @@
 
 MockBluetoothAdapter::~MockBluetoothAdapter() {}
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 void MockBluetoothAdapter::Shutdown() {
 }
 #endif
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h
index 775adee..c5427c29 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.h
+++ b/device/bluetooth/test/mock_bluetooth_adapter.h
@@ -37,7 +37,7 @@
 
   virtual bool IsInitialized() const { return true; }
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
   void Shutdown() override;
 #endif
   MOCK_METHOD1(AddObserver, void(BluetoothAdapter::Observer*));
diff --git a/device/bluetooth/test/mock_bluetooth_advertisement.cc b/device/bluetooth/test/mock_bluetooth_advertisement.cc
index ddba516..746108a 100644
--- a/device/bluetooth/test/mock_bluetooth_advertisement.cc
+++ b/device/bluetooth/test/mock_bluetooth_advertisement.cc
@@ -18,4 +18,4 @@
   success_callback.Run();
 }
 
-}  // namespace chromeos
+}  // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_advertisement.h b/device/bluetooth/test/mock_bluetooth_advertisement.h
index ddaeef4..2079cf0 100644
--- a/device/bluetooth/test/mock_bluetooth_advertisement.h
+++ b/device/bluetooth/test/mock_bluetooth_advertisement.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_
+#ifndef DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_ADVERTISEMENT_H_
+#define DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_ADVERTISEMENT_H_
 
 #include "base/macros.h"
 #include "device/bluetooth/bluetooth_advertisement.h"
@@ -24,6 +24,6 @@
   DISALLOW_COPY_AND_ASSIGN(MockBluetoothAdvertisement);
 };
 
-}  // namespace chromeos
+}  // namespace device
 
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_
+#endif  // DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_ADVERTISEMENT_H_
diff --git a/device/device_tests.gyp b/device/device_tests.gyp
index a49696aea..c7491ac 100644
--- a/device/device_tests.gyp
+++ b/device/device_tests.gyp
@@ -36,22 +36,16 @@
         'battery/battery_status_manager_win_unittest.cc',
         'battery/battery_status_service_unittest.cc',
         'bluetooth/bluetooth_adapter_mac_unittest.mm',
-        'bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc',
         'bluetooth/bluetooth_adapter_unittest.cc',
         'bluetooth/bluetooth_adapter_win_unittest.cc',
-        'bluetooth/bluetooth_advertisement_chromeos_unittest.cc',
         'bluetooth/bluetooth_advertisement_unittest.cc',
-        'bluetooth/bluetooth_audio_sink_chromeos_unittest.cc',
-        'bluetooth/bluetooth_chromeos_unittest.cc',
         'bluetooth/bluetooth_device_unittest.cc',
         'bluetooth/bluetooth_device_win_unittest.cc',
         'bluetooth/bluetooth_discovery_filter_unittest.cc',
         'bluetooth/bluetooth_gatt_characteristic_unittest.cc',
-        'bluetooth/bluetooth_gatt_chromeos_unittest.cc',
         'bluetooth/bluetooth_gatt_service_unittest.cc',
         'bluetooth/bluetooth_low_energy_win_unittest.cc',
         'bluetooth/bluetooth_service_record_win_unittest.cc',
-        'bluetooth/bluetooth_socket_chromeos_unittest.cc',
         'bluetooth/bluetooth_task_manager_win_unittest.cc',
         'bluetooth/bluetooth_uuid_unittest.cc',
         'bluetooth/test/bluetooth_test.cc',
@@ -94,15 +88,27 @@
       'conditions': [
         ['chromeos==1', {
           'dependencies': [
-            '../build/linux/system.gyp:dbus',
             '../chromeos/chromeos.gyp:chromeos_test_support',
             '../chromeos/chromeos.gyp:chromeos_test_support_without_gmock',
-            '../dbus/dbus.gyp:dbus',
           ],
           'sources!': [
             'battery/battery_status_manager_linux_unittest.cc',
           ],
         }],
+        ['chromeos==1 or OS=="linux"', {
+          'dependencies': [
+            '../build/linux/system.gyp:dbus',
+            '../dbus/dbus.gyp:dbus',
+          ],
+          'sources': [
+            'bluetooth/bluetooth_adapter_profile_bluez_unittest.cc',
+            'bluetooth/bluetooth_advertisement_bluez_unittest.cc',
+            'bluetooth/bluetooth_audio_sink_bluez_unittest.cc',
+            'bluetooth/bluetooth_bluez_unittest.cc',
+            'bluetooth/bluetooth_gatt_bluez_unittest.cc',
+            'bluetooth/bluetooth_socket_bluez_unittest.cc',
+          ],
+        }],
         ['OS=="android"', {
           'dependencies!': [
             '../tools/usb_gadget/usb_gadget.gyp:usb_gadget',
diff --git a/device/vibration/android/java/src/org/chromium/device/vibration/VibrationManagerImpl.java b/device/vibration/android/java/src/org/chromium/device/vibration/VibrationManagerImpl.java
index dd8d2755..6a323af 100644
--- a/device/vibration/android/java/src/org/chromium/device/vibration/VibrationManagerImpl.java
+++ b/device/vibration/android/java/src/org/chromium/device/vibration/VibrationManagerImpl.java
@@ -10,6 +10,7 @@
 import android.os.Vibrator;
 import android.util.Log;
 
+import org.chromium.base.VisibleForTesting;
 import org.chromium.mojo.system.MojoException;
 import org.chromium.mojom.device.VibrationManager;
 
@@ -27,9 +28,35 @@
     private final Vibrator mVibrator;
     private final boolean mHasVibratePermission;
 
+    private static AndroidVibratorWrapper sVibratorWrapper;
+
+    /**
+     * Android Vibrator wrapper class provided to test code to extend.
+     */
+    @VisibleForTesting
+    public static class AndroidVibratorWrapper {
+        protected AndroidVibratorWrapper() {}
+
+        public void vibrate(Vibrator vibrator, long milliseconds) {
+            vibrator.vibrate(milliseconds);
+        }
+
+        public void cancel(Vibrator vibrator) {
+            vibrator.cancel();
+        }
+    }
+
+    // Test code can use this function to inject other wrapper for testing.
+    public static void setVibratorWrapperForTesting(AndroidVibratorWrapper wrapper) {
+        sVibratorWrapper = wrapper;
+    }
+
     public VibrationManagerImpl(Context context) {
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+        if (sVibratorWrapper == null) {
+            sVibratorWrapper = new AndroidVibratorWrapper();
+        }
         mHasVibratePermission =
                 context.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 == PackageManager.PERMISSION_GRANTED;
@@ -53,12 +80,12 @@
 
         if (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT
                 && mHasVibratePermission) {
-            mVibrator.vibrate(sanitizedMilliseconds);
+            sVibratorWrapper.vibrate(mVibrator, sanitizedMilliseconds);
         }
     }
 
     @Override
     public void cancel() {
-        if (mHasVibratePermission) mVibrator.cancel();
+        if (mHasVibratePermission) sVibratorWrapper.cancel(mVibrator);
     }
 }
diff --git a/extensions/browser/api/bluetooth/bluetooth_event_router.cc b/extensions/browser/api/bluetooth/bluetooth_event_router.cc
index acd6e41..47920c66 100644
--- a/extensions/browser/api/bluetooth/bluetooth_event_router.cc
+++ b/extensions/browser/api/bluetooth/bluetooth_event_router.cc
@@ -59,6 +59,9 @@
 }
 
 bool BluetoothEventRouter::IsBluetoothSupported() const {
+#if defined(OS_LINUX)
+  return true;
+#endif
   return adapter_.get() ||
          device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable();
 }
diff --git a/extensions/browser/value_store/leveldb_value_store.cc b/extensions/browser/value_store/leveldb_value_store.cc
index 39a1346..c11e655 100644
--- a/extensions/browser/value_store/leveldb_value_store.cc
+++ b/extensions/browser/value_store/leveldb_value_store.cc
@@ -8,9 +8,13 @@
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/process_memory_dump.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/value_store/value_store_util.h"
 #include "third_party/leveldatabase/env_chromium.h"
@@ -59,10 +63,14 @@
       "Extensions.Database.Open." + uma_client_name, 1,
       leveldb_env::LEVELDB_STATUS_MAX, leveldb_env::LEVELDB_STATUS_MAX + 1,
       base::Histogram::kUmaTargetedHistogramFlag);
+  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+      this, "LeveldbValueStore", base::ThreadTaskRunnerHandle::Get());
 }
 
 LeveldbValueStore::~LeveldbValueStore() {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+  base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
+      this);
 
   // Delete the database from disk if it's empty (but only if we managed to
   // open it!). This is safe on destruction, assuming that we have exclusive
@@ -325,6 +333,38 @@
   return !WriteToDb(batch).get();
 }
 
+bool LeveldbValueStore::OnMemoryDump(
+    const base::trace_event::MemoryDumpArgs& args,
+    base::trace_event::ProcessMemoryDump* pmd) {
+  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+
+  // Return true so that the provider is not disabled.
+  if (!db_)
+    return true;
+
+  std::string value;
+  uint64 size;
+  bool res = db_->GetProperty("leveldb.approximate-memory-usage", &value);
+  DCHECK(res);
+  res = base::StringToUint64(value, &size);
+  DCHECK(res);
+
+  auto dump = pmd->CreateAllocatorDump(
+      base::StringPrintf("leveldb/value_store/%s/%p",
+                         open_histogram_->histogram_name().c_str(), this));
+  dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+                  base::trace_event::MemoryAllocatorDump::kUnitsBytes, size);
+
+  // Memory is allocated from system allocator (malloc).
+  const char* system_allocator_name =
+      base::trace_event::MemoryDumpManager::GetInstance()
+          ->system_allocator_pool_name();
+  if (system_allocator_name)
+    pmd->AddSuballocation(dump->guid(), system_allocator_name);
+
+  return true;
+}
+
 scoped_ptr<ValueStore::Error> LeveldbValueStore::EnsureDbIsOpen() {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
 
diff --git a/extensions/browser/value_store/leveldb_value_store.h b/extensions/browser/value_store/leveldb_value_store.h
index 2901660..e7637142 100644
--- a/extensions/browser/value_store/leveldb_value_store.h
+++ b/extensions/browser/value_store/leveldb_value_store.h
@@ -11,6 +11,7 @@
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/memory_dump_provider.h"
 #include "extensions/browser/value_store/value_store.h"
 #include "third_party/leveldatabase/src/include/leveldb/db.h"
 
@@ -20,7 +21,8 @@
 
 // Value store area, backed by a leveldb database.
 // All methods must be run on the FILE thread.
-class LeveldbValueStore : public ValueStore {
+class LeveldbValueStore : public ValueStore,
+                          public base::trace_event::MemoryDumpProvider {
  public:
   // Creates a database bound to |path|. The underlying database won't be
   // opened (i.e. may not be created) until one of the get/set/etc methods are
@@ -56,6 +58,10 @@
   // corruption in the database.
   bool WriteToDbForTest(leveldb::WriteBatch* batch);
 
+  // base::trace_event::MemoryDumpProvider implementation.
+  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
+                    base::trace_event::ProcessMemoryDump* pmd) override;
+
  private:
   // Tries to open the database if it hasn't been opened already.
   scoped_ptr<ValueStore::Error> EnsureDbIsOpen();
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_image.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_image.txt
index 7118391a..2ba1e39 100644
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_image.txt
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_image.txt
@@ -46,7 +46,7 @@
     INVALID_VALUE is generated if <width> or <height> is nonpositive.
 
     INVALID_VALUE is generated if <internalformat> is not one of
-    R8, RGB, RGBA, BGRA_EXT, ATC_RGB_AMD, ATC_RGBA_INTERPOLATED_ALPHA_AMD,
+    RED, RGB, RGBA, BGRA_EXT, ATC_RGB_AMD, ATC_RGBA_INTERPOLATED_ALPHA_AMD,
     COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT5_EXT or
     ETC1_RGB8_OES.
 
@@ -64,7 +64,7 @@
 Dependencies on ARB_texture_rg
 
     If ARB_texture_rg is not supported:
-     * delete any reference to the R8 format.
+     * delete any reference to the RED format.
 
 Dependencies on AMD_compressed_ATC_texture
 
@@ -99,3 +99,4 @@
     4/6/2015    Add BGRA_EXT format.
     2/7/2015    Add R8 format.
     5/13/2015   Add compressed formats.
+    11/5/2015   Change R8 format to RED.
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index f541d91a..f37b82a 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -5486,7 +5486,7 @@
       return capabilities.texture_format_dxt5;
     case GL_ETC1_RGB8_OES:
       return capabilities.texture_format_etc1;
-    case GL_R8:
+    case GL_RED:
     case GL_RGB:
     case GL_RGBA:
     case GL_RGB_YCBCR_422_CHROMIUM:
diff --git a/gpu/command_buffer/service/image_factory.cc b/gpu/command_buffer/service/image_factory.cc
index bcfd121..13b016a 100644
--- a/gpu/command_buffer/service/image_factory.cc
+++ b/gpu/command_buffer/service/image_factory.cc
@@ -19,7 +19,7 @@
 gfx::BufferFormat ImageFactory::DefaultBufferFormatForImageFormat(
     unsigned internalformat) {
   switch (internalformat) {
-    case GL_R8:
+    case GL_RED:
       return gfx::BufferFormat::R_8;
     case GL_RGB:
       return gfx::BufferFormat::BGRX_8888;
diff --git a/gpu/command_buffer/service/memory_program_cache_unittest.cc b/gpu/command_buffer/service/memory_program_cache_unittest.cc
index 7a22eac3..a005db95 100644
--- a/gpu/command_buffer/service/memory_program_cache_unittest.cc
+++ b/gpu/command_buffer/service/memory_program_cache_unittest.cc
@@ -125,11 +125,11 @@
     TestHelper::SetShaderStates(
         gl_.get(), vertex_shader_, true, NULL, NULL, NULL,
         &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map,
-        NULL);
+        NULL, NULL);
     TestHelper::SetShaderStates(
         gl_.get(), fragment_shader_, true, NULL, NULL, NULL,
         &fragment_attrib_map, &fragment_uniform_map, &fragment_varying_map,
-        NULL);
+        NULL, NULL);
   }
 
   void SetExpectationsForSaveLinkedProgram(
diff --git a/gpu/command_buffer/service/mocks.h b/gpu/command_buffer/service/mocks.h
index 0824d8ef..2ef657f 100644
--- a/gpu/command_buffer/service/mocks.h
+++ b/gpu/command_buffer/service/mocks.h
@@ -95,7 +95,7 @@
                     const ShBuiltInResources* resources,
                     ShShaderOutput shader_output_language,
                     ShCompileOptions driver_bug_workarounds));
-  MOCK_CONST_METHOD8(Translate, bool(
+  MOCK_CONST_METHOD9(Translate, bool(
       const std::string& shader_source,
       std::string* info_log,
       std::string* translated_source,
@@ -103,6 +103,7 @@
       AttributeMap* attrib_map,
       UniformMap* uniform_map,
       VaryingMap* varying_map,
+      InterfaceBlockMap* interface_block_map,
       NameMap* name_map));
   MOCK_CONST_METHOD0(
       GetStringForOptionsThatWouldAffectCompilation, std::string());
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
index 94e7bde..83f4e39 100644
--- a/gpu/command_buffer/service/program_manager.cc
+++ b/gpu/command_buffer/service/program_manager.cc
@@ -11,12 +11,14 @@
 
 #include "base/basictypes.h"
 #include "base/command_line.h"
+#include "base/containers/hash_tables.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram.h"
 #include "base/numerics/safe_math.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "gpu/command_buffer/common/gles2_cmd_format.h"
 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
@@ -866,6 +868,7 @@
   GLint success = 0;
   glGetProgramiv(service_id(), GL_LINK_STATUS, &success);
   if (success == GL_TRUE) {
+    GatherInterfaceBlockInfo();
     Update();
     if (link) {
       if (cache) {
@@ -1112,6 +1115,68 @@
   *original_name = name;
 }
 
+template <typename VarT>
+void Program::GetUniformBlockMembers(
+    Shader* shader, const std::vector<VarT>& fields,
+    const std::string& prefix) {
+  for (const VarT& field : fields) {
+    const std::string& full_name =
+        (prefix.empty() ? field.name : prefix + "." + field.name);
+    const std::string& mapped_name = *(shader->GetMappedName(field.name));
+
+    if (field.isStruct()) {
+      for (unsigned int array_element = 0; array_element < field.elementCount();
+           ++array_element) {
+        std::string array_string = base::StringPrintf("[%d]", array_element);
+        const std::string uniform_element_name =
+            full_name + (field.isArray() ? array_string: "");
+        GetUniformBlockMembers(shader, field.fields, uniform_element_name);
+      }
+    } else {
+      sh::Uniform info;
+      info.name = full_name;
+      info.mappedName = mapped_name;
+      info.type = field.type;
+      info.arraySize = field.arraySize;
+      info.precision = field.precision;
+      shader->AddUniformToUniformMap(info);
+    }
+  }
+}
+
+void Program::GetUniformBlockFromInterfaceBlock(
+    Shader* shader, const sh::InterfaceBlock& interface_block) {
+  GLuint program_id = service_id();
+
+  // Don't define this block at all if it's not active in the implementation
+  const std::string* mapped_name = shader->GetMappedName(interface_block.name);
+  GLuint block_index = glGetUniformBlockIndex(program_id, mapped_name->c_str());
+  if (block_index == GL_INVALID_INDEX)
+    return;
+
+  GetUniformBlockMembers(shader, interface_block.fields, "");
+}
+
+void Program::GatherInterfaceBlockInfo() {
+  base::hash_set<std::string> visited_list;
+  for (auto shader : attached_shaders_) {
+    const InterfaceBlockMap& interface_block_map =
+        shader->interface_block_map();
+    for (const auto& key_value : interface_block_map) {
+      const sh::InterfaceBlock& block = key_value.second;
+      // Only 'packed' blocks are allowed to be considered inactive.
+      if (!block.staticUse && block.layout == sh::BLOCKLAYOUT_PACKED)
+        continue;
+
+      if (visited_list.find(block.name) != visited_list.end())
+        continue;
+
+      GetUniformBlockFromInterfaceBlock(shader.get(), block);
+      visited_list.insert(block.name);
+    }
+  }
+}
+
 void Program::AddUniformInfo(
     GLsizei size, GLenum type, GLint location, GLint fake_base_location,
     const std::string& name, const std::string& original_name,
diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h
index bf02f80..737c849 100644
--- a/gpu/command_buffer/service/program_manager.h
+++ b/gpu/command_buffer/service/program_manager.h
@@ -341,6 +341,18 @@
   // Updates the program log info from GL
   void UpdateLogInfo();
 
+  template <typename VarT>
+  void GetUniformBlockMembers(
+      Shader* shader, const std::vector<VarT>& fields,
+      const std::string& prefix);
+
+  // Get UniformBlock from InterfaceBlock
+  void GetUniformBlockFromInterfaceBlock(
+      Shader* shader, const sh::InterfaceBlock& interface_block);
+
+  // Get UniformBlocks info
+  void GatherInterfaceBlockInfo();
+
   // Clears all the uniforms.
   void ClearUniforms(std::vector<uint8>* zero_buffer);
 
diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc
index fe1835e..404017f 100644
--- a/gpu/command_buffer/service/program_manager_unittest.cc
+++ b/gpu/command_buffer/service/program_manager_unittest.cc
@@ -387,11 +387,11 @@
     EXPECT_TRUE(vshader != NULL && fshader != NULL);
     // Set Status
     TestHelper::SetShaderStates(
-        gl_.get(), vshader, true, NULL, NULL, NULL,
-        &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, NULL);
+        gl_.get(), vshader, true, NULL, NULL, NULL, &vertex_attrib_map,
+        &vertex_uniform_map, &vertex_varying_map, NULL, NULL);
     TestHelper::SetShaderStates(
         gl_.get(), fshader, true, NULL, NULL, NULL,
-        &frag_attrib_map, &frag_uniform_map, &frag_varying_map, NULL);
+        &frag_attrib_map, &frag_uniform_map, &frag_varying_map, NULL, NULL);
 
     // Set up program
     Program* program =
@@ -828,13 +828,13 @@
   ASSERT_TRUE(vshader != NULL);
   TestHelper::SetShaderStates(
       gl_.get(), vshader, true, NULL, NULL, NULL,
-      &attrib_map, &uniform_map, &varying_map, NULL);
+      &attrib_map, &uniform_map, &varying_map, NULL, NULL);
   Shader* fshader = shader_manager_.CreateShader(
       kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER);
   ASSERT_TRUE(fshader != NULL);
   TestHelper::SetShaderStates(
       gl_.get(), fshader, true, NULL, NULL, NULL,
-      &attrib_map, &uniform_map, &varying_map, NULL);
+      &attrib_map, &uniform_map, &varying_map, NULL, NULL);
   static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
     { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
     { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, },
@@ -1499,7 +1499,7 @@
   // Set Status
   TestHelper::SetShaderStates(
       gl_.get(), vshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL,
-      NULL);
+      NULL, NULL);
   // Check attrib infos got copied.
   for (AttributeMap::const_iterator it = attrib_map.begin();
        it != attrib_map.end(); ++it) {
@@ -1514,7 +1514,7 @@
   }
   TestHelper::SetShaderStates(
       gl_.get(), fshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL,
-      NULL);
+      NULL, NULL);
 
   // Set up program
   Program* program =
@@ -1583,10 +1583,10 @@
   // Set Status
   TestHelper::SetShaderStates(
       gl_.get(), vshader, true, NULL, NULL, NULL, NULL,
-      &vertex_uniform_map, NULL, NULL);
+      &vertex_uniform_map, NULL, NULL, NULL);
   TestHelper::SetShaderStates(
       gl_.get(), fshader, true, NULL, NULL, NULL, NULL,
-      &frag_uniform_map, NULL, NULL);
+      &frag_uniform_map, NULL, NULL, NULL);
 
   // Set up program
   Program* program =
@@ -2204,9 +2204,11 @@
       kFragmentInput3Type, kFragmentInput3Size, kFragmentInput3Precision,
       kFragmentInput3StaticUse, kFragmentInput3Name);
   TestHelper::SetShaderStates(gl_.get(), vshader, true, nullptr, nullptr,
-                              nullptr, nullptr, nullptr, &varying_map, nullptr);
+                              nullptr, nullptr, nullptr, &varying_map, nullptr,
+                              nullptr);
   TestHelper::SetShaderStates(gl_.get(), fshader, true, nullptr, nullptr,
-                              nullptr, nullptr, nullptr, &varying_map, nullptr);
+                              nullptr, nullptr, nullptr, &varying_map, nullptr,
+                              nullptr);
   Program* program =
       manager_->CreateProgram(kClientProgramId, kServiceProgramId);
   ASSERT_TRUE(program != NULL);
diff --git a/gpu/command_buffer/service/shader_manager.cc b/gpu/command_buffer/service/shader_manager.cc
index 0ad8bf0..37cc4f3 100644
--- a/gpu/command_buffer/service/shader_manager.cc
+++ b/gpu/command_buffer/service/shader_manager.cc
@@ -76,6 +76,7 @@
                                          &attrib_map_,
                                          &uniform_map_,
                                          &varying_map_,
+                                         &interface_block_map_,
                                          &name_map_);
     if (!success) {
       return;
@@ -201,6 +202,15 @@
   return NULL;
 }
 
+const std::string* Shader::GetInterfaceBlockMappedName(
+    const std::string& original_name) const {
+  for (const auto& key_value : interface_block_map_) {
+    if (key_value.second.name == original_name)
+      return &(key_value.first);
+  }
+  return NULL;
+}
+
 const std::string* Shader::GetOriginalNameFromHashedName(
     const std::string& hashed_name) const {
   NameMap::const_iterator it = name_map_.find(hashed_name);
@@ -209,6 +219,15 @@
   return NULL;
 }
 
+const std::string* Shader::GetMappedName(
+    const std::string& original_name) const {
+  for (const auto& key_value : name_map_) {
+    if (key_value.second == original_name)
+      return &(key_value.first);
+  }
+  return NULL;
+}
+
 const sh::Uniform* Shader::GetUniformInfo(const std::string& name) const {
   UniformMap::const_iterator it = uniform_map_.find(GetTopVariableName(name));
   return it != uniform_map_.end() ? &it->second : NULL;
@@ -219,6 +238,13 @@
   return it != varying_map_.end() ? &it->second : NULL;
 }
 
+const sh::InterfaceBlock* Shader::GetInterfaceBlockInfo(
+    const std::string& name) const {
+  InterfaceBlockMap::const_iterator it =
+      interface_block_map_.find(GetTopVariableName(name));
+  return it != interface_block_map_.end() ? &it->second : NULL;
+}
+
 ShaderManager::ShaderManager() {}
 
 ShaderManager::~ShaderManager() {
diff --git a/gpu/command_buffer/service/shader_manager.h b/gpu/command_buffer/service/shader_manager.h
index 1f97f42..aa115de 100644
--- a/gpu/command_buffer/service/shader_manager.h
+++ b/gpu/command_buffer/service/shader_manager.h
@@ -85,6 +85,8 @@
   const sh::Attribute* GetAttribInfo(const std::string& name) const;
   const sh::Uniform* GetUniformInfo(const std::string& name) const;
   const sh::Varying* GetVaryingInfo(const std::string& name) const;
+  const sh::InterfaceBlock* GetInterfaceBlockInfo(
+      const std::string& name) const;
 
   // If the original_name is not found, return NULL.
   const std::string* GetAttribMappedName(
@@ -98,10 +100,17 @@
   const std::string* GetVaryingMappedName(
       const std::string& original_name) const;
 
+  // If the original_name is not found, return NULL.
+  const std::string* GetInterfaceBlockMappedName(
+      const std::string& original_name) const;
+
   // If the hashed_name is not found, return NULL.
   const std::string* GetOriginalNameFromHashedName(
       const std::string& hashed_name) const;
 
+  const std::string* GetMappedName(
+      const std::string& original_name) const;
+
   const std::string& log_info() const {
     return log_info_;
   }
@@ -135,6 +144,11 @@
   }
 
   // Used by program cache.
+  const InterfaceBlockMap& interface_block_map() const {
+    return interface_block_map_;
+  }
+
+  // Used by program cache.
   void set_attrib_map(const AttributeMap& attrib_map) {
     // copied because cache might be cleared
     attrib_map_ = AttributeMap(attrib_map);
@@ -152,6 +166,16 @@
     varying_map_ = VaryingMap(varying_map);
   }
 
+  // Used by program cache.
+  void set_interface_block_map(const InterfaceBlockMap& interface_block_map) {
+    // copied because cache might be cleared
+    interface_block_map_ = InterfaceBlockMap(interface_block_map);
+  }
+
+  void AddUniformToUniformMap(sh::Uniform uniform) {
+    uniform_map_[uniform.mappedName] = uniform;
+  }
+
  private:
   friend class base::RefCounted<Shader>;
   friend class ShaderManager;
@@ -211,6 +235,7 @@
   AttributeMap attrib_map_;
   UniformMap uniform_map_;
   VaryingMap varying_map_;
+  InterfaceBlockMap interface_block_map_;
 
   // The name hashing info when the shader was last compiled.
   NameMap name_map_;
diff --git a/gpu/command_buffer/service/shader_manager_unittest.cc b/gpu/command_buffer/service/shader_manager_unittest.cc
index 87729b1..c125cfe6 100644
--- a/gpu/command_buffer/service/shader_manager_unittest.cc
+++ b/gpu/command_buffer/service/shader_manager_unittest.cc
@@ -190,7 +190,7 @@
 
   TestHelper::SetShaderStates(
       gl_.get(), shader1, true, &kLog, &kTranslatedSource, NULL,
-      &attrib_map, &uniform_map, &varying_map, NULL);
+      &attrib_map, &uniform_map, &varying_map, NULL, NULL);
   EXPECT_TRUE(shader1->valid());
   // When compilation succeeds, no log is recorded.
   EXPECT_STREQ("", shader1->log_info().c_str());
@@ -237,7 +237,7 @@
   // Compile failure case.
   TestHelper::SetShaderStates(
       gl_.get(), shader1, false, &kLog, &kTranslatedSource, NULL,
-      &attrib_map, &uniform_map, &varying_map, NULL);
+      &attrib_map, &uniform_map, &varying_map, NULL, NULL);
   EXPECT_FALSE(shader1->valid());
   EXPECT_STREQ(kLog.c_str(), shader1->log_info().c_str());
   EXPECT_STREQ("", shader1->translated_source().c_str());
diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc
index b852d2aa..92c7f9d 100644
--- a/gpu/command_buffer/service/shader_translator.cc
+++ b/gpu/command_buffer/service/shader_translator.cc
@@ -72,6 +72,19 @@
   }
 }
 
+void GetInterfaceBlocks(ShHandle compiler, InterfaceBlockMap* var_map) {
+  if (!var_map)
+    return;
+  var_map->clear();
+  const std::vector<sh::InterfaceBlock>* interface_blocks =
+      ShGetInterfaceBlocks(compiler);
+  if (interface_blocks) {
+    for (const auto& block : *interface_blocks) {
+      (*var_map)[block.mappedName] = block;
+    }
+  }
+}
+
 void GetNameHashingInfo(ShHandle compiler, NameMap* name_map) {
   if (!name_map)
     return;
@@ -192,6 +205,7 @@
                                  AttributeMap* attrib_map,
                                  UniformMap* uniform_map,
                                  VaryingMap* varying_map,
+                                 InterfaceBlockMap* interface_block_map,
                                  NameMap* name_map) const {
   // Make sure this instance is initialized.
   DCHECK(compiler_ != NULL);
@@ -214,6 +228,7 @@
     GetAttributes(compiler_, attrib_map);
     GetUniforms(compiler_, uniform_map);
     GetVaryings(compiler_, varying_map);
+    GetInterfaceBlocks(compiler_, interface_block_map);
     // Get info for name hashing.
     GetNameHashingInfo(compiler_, name_map);
   }
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h
index 6e7628f..58ba69f 100644
--- a/gpu/command_buffer/service/shader_translator.h
+++ b/gpu/command_buffer/service/shader_translator.h
@@ -26,6 +26,7 @@
 typedef base::hash_map<std::string, sh::Attribute> AttributeMap;
 typedef base::hash_map<std::string, sh::Uniform> UniformMap;
 typedef base::hash_map<std::string, sh::Varying> VaryingMap;
+typedef base::hash_map<std::string, sh::InterfaceBlock> InterfaceBlockMap;
 // Mapping between hashed name and original name.
 typedef base::hash_map<std::string, std::string> NameMap;
 
@@ -56,6 +57,7 @@
                          AttributeMap* attrib_map,
                          UniformMap* uniform_map,
                          VaryingMap* varying_map,
+                         InterfaceBlockMap* interface_block_map,
                          NameMap* name_map) const = 0;
 
   // Return a string that is unique for a specfic set of options that would
@@ -106,6 +108,7 @@
                  AttributeMap* attrib_map,
                  UniformMap* uniform_map,
                  VaryingMap* varying_map,
+                 InterfaceBlockMap* interface_block_map,
                  NameMap* name_map) const override;
 
   std::string GetStringForOptionsThatWouldAffectCompilation() const override;
diff --git a/gpu/command_buffer/service/shader_translator_unittest.cc b/gpu/command_buffer/service/shader_translator_unittest.cc
index 0c60b44..eff11c1ca 100644
--- a/gpu/command_buffer/service/shader_translator_unittest.cc
+++ b/gpu/command_buffer/service/shader_translator_unittest.cc
@@ -48,6 +48,43 @@
   ShShaderOutput shader_output_language_;
 };
 
+class ES3ShaderTranslatorTest : public testing::Test {
+ public:
+  ES3ShaderTranslatorTest() {
+    shader_output_language_ =
+        ShaderTranslator::GetShaderOutputLanguageForContext(
+            gfx::GLVersionInfo("3.0", "", ""));
+  }
+
+  ~ES3ShaderTranslatorTest() override {}
+
+ protected:
+  void SetUp() override {
+    ShBuiltInResources resources;
+    ShInitBuiltInResources(&resources);
+    resources.MaxExpressionComplexity = 32;
+    resources.MaxCallStackDepth = 32;
+
+    vertex_translator_ = new ShaderTranslator();
+    fragment_translator_ = new ShaderTranslator();
+
+    ASSERT_TRUE(vertex_translator_->Init(GL_VERTEX_SHADER, SH_GLES3_SPEC,
+                                         &resources, shader_output_language_,
+                                         SH_EMULATE_BUILT_IN_FUNCTIONS));
+    ASSERT_TRUE(fragment_translator_->Init(GL_FRAGMENT_SHADER, SH_GLES3_SPEC,
+                                           &resources, shader_output_language_,
+                                           static_cast<ShCompileOptions>(0)));
+  }
+  void TearDown() override {
+    vertex_translator_ = NULL;
+    fragment_translator_ = NULL;
+  }
+
+  scoped_refptr<ShaderTranslator> vertex_translator_;
+  scoped_refptr<ShaderTranslator> fragment_translator_;
+  ShShaderOutput shader_output_language_;
+};
+
 TEST_F(ShaderTranslatorTest, ValidVertexShader) {
   const char* shader =
       "void main() {\n"
@@ -60,6 +97,7 @@
   AttributeMap attrib_map;
   UniformMap uniform_map;
   VaryingMap varying_map;
+  InterfaceBlockMap interface_block_map;
   NameMap name_map;
   EXPECT_TRUE(vertex_translator_->Translate(shader,
                                             &info_log,
@@ -68,6 +106,7 @@
                                             &attrib_map,
                                             &uniform_map,
                                             &varying_map,
+                                            &interface_block_map,
                                             &name_map));
   // Info log must be NULL.
   EXPECT_TRUE(info_log.empty());
@@ -77,6 +116,7 @@
   // varying: gl_Position.
   EXPECT_TRUE(attrib_map.empty());
   EXPECT_TRUE(uniform_map.empty());
+  EXPECT_TRUE(interface_block_map.empty());
   EXPECT_EQ(1u, varying_map.size());
   // There should be no name mapping.
   EXPECT_TRUE(name_map.empty());
@@ -95,6 +135,7 @@
   AttributeMap attrib_map;
   UniformMap uniform_map;
   VaryingMap varying_map;
+  InterfaceBlockMap interface_block_map;
   NameMap name_map;
   EXPECT_FALSE(vertex_translator_->Translate(bad_shader,
                                              &info_log,
@@ -103,15 +144,18 @@
                                              &attrib_map,
                                              &uniform_map,
                                              &varying_map,
+                                             &interface_block_map,
                                              &name_map));
   // Info log must be valid and non-empty.
   ASSERT_FALSE(info_log.empty());
   // Translated shader must be NULL.
   EXPECT_TRUE(translated_source.empty());
-  // There should be no attributes, uniforms, varyings, or name mapping.
+  // There should be no attributes, uniforms, varyings, interface block or
+  // name mapping.
   EXPECT_TRUE(attrib_map.empty());
   EXPECT_TRUE(uniform_map.empty());
   EXPECT_TRUE(varying_map.empty());
+  EXPECT_TRUE(interface_block_map.empty());
   EXPECT_TRUE(name_map.empty());
 
   // Try a good shader after bad.
@@ -123,9 +167,11 @@
                                             &attrib_map,
                                             &uniform_map,
                                             &varying_map,
+                                            &interface_block_map,
                                             &name_map));
   EXPECT_TRUE(info_log.empty());
   EXPECT_FALSE(translated_source.empty());
+  EXPECT_TRUE(interface_block_map.empty());
 }
 
 TEST_F(ShaderTranslatorTest, ValidFragmentShader) {
@@ -140,6 +186,7 @@
   AttributeMap attrib_map;
   UniformMap uniform_map;
   VaryingMap varying_map;
+  InterfaceBlockMap interface_block_map;
   NameMap name_map;
   EXPECT_TRUE(fragment_translator_->Translate(shader,
                                               &info_log,
@@ -148,15 +195,18 @@
                                               &attrib_map,
                                               &uniform_map,
                                               &varying_map,
+                                              &interface_block_map,
                                               &name_map));
   // Info log must be NULL.
   EXPECT_TRUE(info_log.empty());
   // Translated shader must be valid and non-empty.
   ASSERT_FALSE(translated_source.empty());
-  // There should be no attributes, uniforms, varyings, or name mapping.
+  // There should be no attributes, uniforms, varyings, interface block or
+  // name mapping.
   EXPECT_TRUE(attrib_map.empty());
   EXPECT_TRUE(uniform_map.empty());
   EXPECT_TRUE(varying_map.empty());
+  EXPECT_TRUE(interface_block_map.empty());
   EXPECT_TRUE(name_map.empty());
 }
 
@@ -168,6 +218,7 @@
   AttributeMap attrib_map;
   UniformMap uniform_map;
   VaryingMap varying_map;
+  InterfaceBlockMap interface_block_map;
   NameMap name_map;
   // An invalid shader should fail.
   EXPECT_FALSE(fragment_translator_->Translate(shader,
@@ -177,12 +228,14 @@
                                                &attrib_map,
                                                &uniform_map,
                                                &varying_map,
+                                               &interface_block_map,
                                                &name_map));
   // Info log must be valid and non-empty.
   EXPECT_FALSE(info_log.empty());
   // Translated shader must be NULL.
   EXPECT_TRUE(translated_source.empty());
-  // There should be no attributes or uniforms.
+  // There should be no attributes, uniforms, varyings, interface block or
+  // name mapping.
   EXPECT_TRUE(attrib_map.empty());
   EXPECT_TRUE(uniform_map.empty());
   EXPECT_TRUE(varying_map.empty());
@@ -201,6 +254,7 @@
   AttributeMap attrib_map;
   UniformMap uniform_map;
   VaryingMap varying_map;
+  InterfaceBlockMap interface_block_map;
   NameMap name_map;
   EXPECT_TRUE(vertex_translator_->Translate(shader,
                                             &info_log,
@@ -209,6 +263,7 @@
                                             &attrib_map,
                                             &uniform_map,
                                             &varying_map,
+                                            &interface_block_map,
                                             &name_map));
   // Info log must be NULL.
   EXPECT_TRUE(info_log.empty());
@@ -216,6 +271,8 @@
   EXPECT_FALSE(translated_source.empty());
   // There should be no uniforms.
   EXPECT_TRUE(uniform_map.empty());
+  // There should be no interface blocks.
+  EXPECT_TRUE(interface_block_map.empty());
   // There should be one attribute with following characteristics:
   // name:vPosition type:GL_FLOAT_VEC4 size:0.
   EXPECT_EQ(1u, attrib_map.size());
@@ -245,6 +302,7 @@
   AttributeMap attrib_map;
   UniformMap uniform_map;
   VaryingMap varying_map;
+  InterfaceBlockMap interface_block_map;
   NameMap name_map;
   EXPECT_TRUE(fragment_translator_->Translate(shader,
                                               &info_log,
@@ -253,6 +311,7 @@
                                               &attrib_map,
                                               &uniform_map,
                                               &varying_map,
+                                              &interface_block_map,
                                               &name_map));
   // Info log must be NULL.
   EXPECT_TRUE(info_log.empty());
@@ -260,6 +319,8 @@
   EXPECT_FALSE(translated_source.empty());
   // There should be no attributes.
   EXPECT_TRUE(attrib_map.empty());
+  // There should be no interface blocks.
+  EXPECT_TRUE(interface_block_map.empty());
   // There should be two uniforms with following characteristics:
   // 1. name:bar[0].foo.color[0] type:GL_FLOAT_VEC4 size:1
   // 2. name:bar[1].foo.color[0] type:GL_FLOAT_VEC4 size:1
@@ -285,6 +346,102 @@
   EXPECT_STREQ("bar[1].foo.color[0]", original_name.c_str());
 }
 
+
+TEST_F(ES3ShaderTranslatorTest, InvalidInterfaceBlocks) {
+  const char* shader =
+      "#version 300 es\n"
+      "precision mediump float;\n"
+      "layout(location=0) out vec4 oColor;\n"
+      "uniform Color {\n"
+      "  float red;\n"
+      "  float green;\n"
+      "  float blue;\n"
+      "};\n"
+      "uniform Color2 {\n"
+      "  float R;\n"
+      "  float green;\n"
+      "  float B;\n"
+      "};\n"
+      "void main() {\n"
+      "  oColor = vec4(red * R, green * green, blue * B, 1.0);\n"
+      "}";
+
+  std::string info_log, translated_source;
+  int shader_version;
+  AttributeMap attrib_map;
+  UniformMap uniform_map;
+  VaryingMap varying_map;
+  InterfaceBlockMap interface_block_map;
+  NameMap name_map;
+  EXPECT_FALSE(fragment_translator_->Translate(shader,
+                                               &info_log,
+                                               &translated_source,
+                                               &shader_version,
+                                               &attrib_map,
+                                               &uniform_map,
+                                               &varying_map,
+                                               &interface_block_map,
+                                               &name_map));
+  // Info log must be valid and non-empty.
+  ASSERT_FALSE(info_log.empty());
+  // Translated shader must be NULL.
+  EXPECT_TRUE(translated_source.empty());
+  // There should be no attributes, uniforms, varyings, interface block or
+  // name mapping.
+  EXPECT_TRUE(attrib_map.empty());
+  EXPECT_TRUE(uniform_map.empty());
+  EXPECT_TRUE(varying_map.empty());
+  EXPECT_TRUE(interface_block_map.empty());
+  EXPECT_TRUE(name_map.empty());
+}
+
+TEST_F(ES3ShaderTranslatorTest, GetInterfaceBlocks) {
+  const char* shader =
+      "#version 300 es\n"
+      "precision mediump float;\n"
+      "layout(location=0) out vec4 oColor;\n"
+      "uniform Color {\n"
+      "  float red;\n"
+      "  float green;\n"
+      "  float blue;\n"
+      "};\n"
+      "void main() {\n"
+      "  oColor = vec4(red, green, blue, 1.0);\n"
+      "}";
+
+  std::string info_log, translated_source;
+  int shader_version;
+  AttributeMap attrib_map;
+  UniformMap uniform_map;
+  VaryingMap varying_map;
+  InterfaceBlockMap interface_block_map;
+  NameMap name_map;
+  EXPECT_TRUE(fragment_translator_->Translate(shader,
+                                              &info_log,
+                                              &translated_source,
+                                              &shader_version,
+                                              &attrib_map,
+                                              &uniform_map,
+                                              &varying_map,
+                                              &interface_block_map,
+                                              &name_map));
+  // Info log must be NULL.
+  EXPECT_TRUE(info_log.empty());
+  // Translated shader must be valid and non-empty.
+  EXPECT_FALSE(translated_source.empty());
+  // There should be no attributes.
+  EXPECT_TRUE(attrib_map.empty());
+  // There should be one block in interface_block_map
+  EXPECT_EQ(1u, interface_block_map.size());
+  InterfaceBlockMap::const_iterator iter;
+  for (iter = interface_block_map.begin();
+       iter != interface_block_map.end(); ++iter) {
+    if (iter->second.name == "Color")
+      break;
+  }
+  EXPECT_TRUE(iter != interface_block_map.end());
+}
+
 TEST_F(ShaderTranslatorTest, OptionsString) {
   scoped_refptr<ShaderTranslator> translator_1 = new ShaderTranslator();
   scoped_refptr<ShaderTranslator> translator_2 = new ShaderTranslator();
@@ -352,7 +509,7 @@
   int shader_version;
   EXPECT_TRUE(translator->Translate(kShader, nullptr, &translated_source,
                                     &shader_version, nullptr, nullptr, nullptr,
-                                    nullptr));
+                                    nullptr, nullptr));
 
   std::string expected_version_directive = testing::get<1>(GetParam());
   if (expected_version_directive.empty()) {
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc
index 066e38a..c9beda9 100644
--- a/gpu/command_buffer/service/test_helper.cc
+++ b/gpu/command_buffer/service/test_helper.cc
@@ -923,6 +923,7 @@
       const AttributeMap* const expected_attrib_map,
       const UniformMap* const expected_uniform_map,
       const VaryingMap* const expected_varying_map,
+      const InterfaceBlockMap* const expected_interface_block_map,
       const NameMap* const expected_name_map) {
   const std::string empty_log_info;
   const std::string* log_info = (expected_log_info && !expected_valid) ?
@@ -943,6 +944,10 @@
   const VaryingMap empty_varying_map;
   const VaryingMap* varying_map = (expected_varying_map && expected_valid) ?
       expected_varying_map : &empty_varying_map;
+  const InterfaceBlockMap empty_interface_block_map;
+  const InterfaceBlockMap* interface_block_map =
+      (expected_interface_block_map && expected_valid) ?
+      expected_interface_block_map : &empty_interface_block_map;
   const NameMap empty_name_map;
   const NameMap* name_map = (expected_name_map && expected_valid) ?
       expected_name_map : &empty_name_map;
@@ -956,6 +961,7 @@
                                           NotNull(),  // attrib_map
                                           NotNull(),  // uniform_map
                                           NotNull(),  // varying_map
+                                          NotNull(),  // interface_block_map
                                           NotNull()))  // name_map
       .WillOnce(DoAll(SetArgumentPointee<1>(*log_info),
                       SetArgumentPointee<2>(*translated_source),
@@ -963,7 +969,8 @@
                       SetArgumentPointee<4>(*attrib_map),
                       SetArgumentPointee<5>(*uniform_map),
                       SetArgumentPointee<6>(*varying_map),
-                      SetArgumentPointee<7>(*name_map),
+                      SetArgumentPointee<7>(*interface_block_map),
+                      SetArgumentPointee<8>(*name_map),
                       Return(expected_valid)))
       .RetiresOnSaturation();
   if (expected_valid) {
@@ -986,7 +993,8 @@
 // static
 void TestHelper::SetShaderStates(
       ::gfx::MockGLInterface* gl, Shader* shader, bool valid) {
-  SetShaderStates(gl, shader, valid, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+  SetShaderStates(
+      gl, shader, valid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 }
 
 // static
diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h
index 45297ee..33c91fb 100644
--- a/gpu/command_buffer/service/test_helper.h
+++ b/gpu/command_buffer/service/test_helper.h
@@ -157,6 +157,7 @@
       const AttributeMap* const expected_attrib_map,
       const UniformMap* const expected_uniform_map,
       const VaryingMap* const expected_varying_map,
+      const InterfaceBlockMap* const expected_interface_block_map,
       const NameMap* const expected_name_map);
 
   static void SetShaderStates(
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
index 0852d01..18b1e8d 100644
--- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
+++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
@@ -127,7 +127,7 @@
 GLenum InternalFormat(gfx::BufferFormat format) {
   switch (format) {
     case gfx::BufferFormat::R_8:
-      return GL_R8;
+      return GL_RED;
     case gfx::BufferFormat::RGBA_4444:
     case gfx::BufferFormat::RGBA_8888:
       return GL_RGBA;
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc
index ae18f94..ebaed09 100644
--- a/ios/chrome/browser/chrome_switches.cc
+++ b/ios/chrome/browser/chrome_switches.cc
@@ -42,6 +42,9 @@
 // Disables the tab switcher.
 const char kDisableTabSwitcher[] = "disable-tab-switcher";
 
+// Disable the snapshots lru cache.
+const char kDisableLRUSnapshotCache[] = "disable-lru-snapshot-cache";
+
 // Enables Contextual Search.
 const char kEnableContextualSearch[] = "enable-contextual-search";
 
@@ -75,6 +78,9 @@
 // Enables the tab switcher.
 const char kEnableTabSwitcher[] = "enable-tab-switcher";
 
+// Enables the snapshot lru cache.
+const char kEnableLRUSnapshotCache[] = "enable-lru-snapshot-cache";
+
 // Enables the recording of metrics reports but disables reporting. In contrast
 // to kDisableMetrics, this executes all the code that a normal client would
 // use for reporting, except the report is dropped rather than sent to the
diff --git a/ios/chrome/browser/chrome_switches.h b/ios/chrome/browser/chrome_switches.h
index f1c590ef..6d452ca 100644
--- a/ios/chrome/browser/chrome_switches.h
+++ b/ios/chrome/browser/chrome_switches.h
@@ -18,6 +18,7 @@
 extern const char kDisableNTPFavicons[];
 extern const char kDisableOfflineAutoReload[];
 extern const char kDisableTabSwitcher[];
+extern const char kDisableLRUSnapshotCache[];
 
 extern const char kEnableContextualSearch[];
 extern const char kEnableCredentialManagerAPI[];
@@ -29,6 +30,7 @@
 extern const char kEnableOfflineAutoReload[];
 extern const char kEnableReaderModeToolbarIcon[];
 extern const char kEnableTabSwitcher[];
+extern const char kEnableLRUSnapshotCache[];
 
 extern const char kIOSMetricsRecordingOnly[];
 extern const char kUserAgent[];
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h
index 7f13f9e06..a284e187 100644
--- a/ios/chrome/browser/experimental_flags.h
+++ b/ios/chrome/browser/experimental_flags.h
@@ -23,6 +23,9 @@
 // only whether the trial state will be checked in the default state.
 void SetWKWebViewTrialEligibility(bool eligible);
 
+// Whether the lru snapshot cache experiment is enabled.
+bool IsLRUSnapshotCacheEnabled();
+
 // Whether the app uses WKWebView instead of UIWebView.
 // The returned value will not change within a given session.
 bool IsWKWebViewEnabled();
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm
index 32bb7bb2..e6714a4 100644
--- a/ios/chrome/browser/experimental_flags.mm
+++ b/ios/chrome/browser/experimental_flags.mm
@@ -54,6 +54,22 @@
                                            : WKWebViewEligibility::INELIGIBLE;
 }
 
+bool IsLRUSnapshotCacheEnabled() {
+  // Check if the experimental flag is forced on or off.
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kEnableLRUSnapshotCache)) {
+    return true;
+  } else if (command_line->HasSwitch(switches::kDisableLRUSnapshotCache)) {
+    return false;
+  }
+
+  // Check if the finch experiment is turned on.
+  std::string group_name =
+      base::FieldTrialList::FindFullName("IOSLRUSnapshotCache");
+  return base::StartsWith(group_name, "Enabled",
+                          base::CompareCase::INSENSITIVE_ASCII);
+}
+
 bool IsWKWebViewEnabled() {
   // If g_wkwebview_trial_eligibility hasn't been set, default it to
   // ineligibile. This ensures future calls to try to set it will DCHECK.
diff --git a/ios/chrome/browser/snapshots/lru_cache.h b/ios/chrome/browser/snapshots/lru_cache.h
new file mode 100644
index 0000000..872a236
--- /dev/null
+++ b/ios/chrome/browser/snapshots/lru_cache.h
@@ -0,0 +1,68 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SNAPSHOTS_LRU_CACHE_H_
+#define IOS_CHROME_BROWSER_SNAPSHOTS_LRU_CACHE_H_
+
+#import <Foundation/Foundation.h>
+
+// The LRUCache delegate is called before an item is evicted from the cache.
+@protocol LRUCacheDelegate
+
+- (void)lruCacheWillEvictObject:(id<NSObject>)object;
+
+@end
+
+// This class implements a cache with a limited size. Once the cache reach its
+// size limit, it will start to evict items in a Least Recently Used order
+// (where the term "used" is determined in terms of query to the cache).
+@interface LRUCache : NSObject
+
+// The delegate of the LRUCache called when objects are evicted from the cache.
+@property(nonatomic, assign) id<LRUCacheDelegate> delegate;
+
+// The maximum amount of items that the cache can hold before starting to
+// evict. The value 0 is used to signify that the cache can hold an unlimited
+// amount of elements (i.e. never evicts).
+@property(nonatomic, readonly) NSUInteger maxCacheSize;
+
+// Use the initWithCacheSize: designated initializer. The is no good general
+// default value for the cache size.
+- (instancetype)init NS_UNAVAILABLE;
+
+// |maxCacheSize| value is used to specify the maximum amount of items that the
+// cache can hold before starting to evict items.
+- (instancetype)initWithCacheSize:(NSUInteger)maxCacheSize
+    NS_DESIGNATED_INITIALIZER;
+
+// Query the cache for an item corresponding to the |key|. Returns nil if there
+// is no item corresponding to that key.
+- (id)objectForKey:(id<NSObject>)key;
+
+// Adds the pair |key|, |obj| to the cache. If the value of the maxCacheSize
+// property is non zero, the cache may evict an elements if the maximum cache
+// size is reached. If the |key| is already present in the cache, the value for
+// that key is replaced by |object|. For any evicted object and if the delegate
+// is
+// non nil, it will receive a call to the lruCacheWillEvictObject: selector.
+- (void)setObject:(id<NSObject>)object forKey:(NSObject*)key;
+
+// Remove the key, value pair corresponding to the given |key|. If the delegate
+// is non nil, it will receive a call to the lruCacheWillEvictObject: selector.
+- (void)removeObjectForKey:(id<NSObject>)key;
+
+// Remove all objects from the cache. For all evicted objects and if the
+// delegate is non nil, it will receive a call to the lruCacheWillEvictObject:
+// selector.
+- (void)removeAllObjects;
+
+// Returns the amount of items that the cache currently hold.
+- (NSUInteger)count;
+
+// Returns true if the cache is empty.
+- (BOOL)isEmpty;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_SNAPSHOTS_LRU_CACHE_H_
diff --git a/ios/chrome/browser/snapshots/lru_cache.mm b/ios/chrome/browser/snapshots/lru_cache.mm
new file mode 100644
index 0000000..0109269
--- /dev/null
+++ b/ios/chrome/browser/snapshots/lru_cache.mm
@@ -0,0 +1,135 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/snapshots/lru_cache.h"
+
+#include "base/containers/hash_tables.h"
+#include "base/containers/mru_cache.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace {
+
+class MRUCacheNSObjectDelegate {
+ public:
+  MRUCacheNSObjectDelegate(id<LRUCacheDelegate> delegate)
+      : delegate_(delegate) {}
+
+  MRUCacheNSObjectDelegate(const MRUCacheNSObjectDelegate& other) = default;
+
+  void operator()(const base::scoped_nsprotocol<id<NSObject>>& payload) const {
+    [delegate_ lruCacheWillEvictObject:payload.get()];
+  }
+
+ private:
+  id<LRUCacheDelegate> delegate_;  // Weak.
+};
+
+struct NSObjectEqualTo {
+  bool operator()(const base::scoped_nsprotocol<id<NSObject>>& obj1,
+                  const base::scoped_nsprotocol<id<NSObject>>& obj2) const {
+    return [obj1 isEqual:obj2];
+  }
+};
+
+struct NSObjectHash {
+  std::size_t operator()(
+      const base::scoped_nsprotocol<id<NSObject>>& obj) const {
+    return [obj hash];
+  }
+};
+
+template <class KeyType, class ValueType>
+struct MRUCacheNSObjectHashMap {
+  typedef base::hash_map<KeyType, ValueType, NSObjectHash, NSObjectEqualTo>
+      Type;
+};
+
+class NSObjectMRUCache
+    : public base::MRUCacheBase<base::scoped_nsprotocol<id<NSObject>>,
+                                base::scoped_nsprotocol<id<NSObject>>,
+                                MRUCacheNSObjectDelegate,
+                                MRUCacheNSObjectHashMap> {
+ private:
+  typedef base::MRUCacheBase<base::scoped_nsprotocol<id<NSObject>>,
+                             base::scoped_nsprotocol<id<NSObject>>,
+                             MRUCacheNSObjectDelegate,
+                             MRUCacheNSObjectHashMap> ParentType;
+
+ public:
+  NSObjectMRUCache(typename ParentType::size_type max_size,
+                   const MRUCacheNSObjectDelegate& deletor)
+      : ParentType(max_size, deletor) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NSObjectMRUCache);
+};
+
+}  // namespace
+
+@interface LRUCache ()<LRUCacheDelegate>
+@end
+
+@implementation LRUCache {
+  scoped_ptr<NSObjectMRUCache> _cache;
+}
+
+@synthesize delegate = _delegate;
+@synthesize maxCacheSize = _maxCacheSize;
+
+- (instancetype)init {
+  NOTREACHED();  // Use initWithCacheSize: instead.
+  return nil;
+}
+
+- (instancetype)initWithCacheSize:(NSUInteger)maxCacheSize {
+  self = [super init];
+  if (self) {
+    _maxCacheSize = maxCacheSize;
+    MRUCacheNSObjectDelegate cacheDelegateDeletor(self);
+    _cache.reset(new NSObjectMRUCache(self.maxCacheSize, cacheDelegateDeletor));
+  }
+  return self;
+}
+
+- (id)objectForKey:(id<NSObject>)key {
+  base::scoped_nsprotocol<id<NSObject>> keyObj([key retain]);
+  auto it = _cache->Get(keyObj);
+  if (it == _cache->end())
+    return nil;
+  return it->second.get();
+}
+
+- (void)setObject:(id<NSObject>)value forKey:(NSObject*)key {
+  base::scoped_nsprotocol<id<NSObject>> keyObj([key copy]);
+  base::scoped_nsprotocol<id<NSObject>> valueObj([value retain]);
+  _cache->Put(keyObj, valueObj);
+}
+
+- (void)removeObjectForKey:(id<NSObject>)key {
+  base::scoped_nsprotocol<id<NSObject>> keyObj([key retain]);
+  auto it = _cache->Peek(keyObj);
+  if (it != _cache->end())
+    _cache->Erase(it);
+}
+
+- (void)removeAllObjects {
+  _cache->Clear();
+}
+
+- (NSUInteger)count {
+  return _cache->size();
+}
+
+- (BOOL)isEmpty {
+  return _cache->empty();
+}
+
+#pragma mark - Private
+
+- (void)lruCacheWillEvictObject:(id<NSObject>)obj {
+  [self.delegate lruCacheWillEvictObject:obj];
+}
+
+@end
diff --git a/ios/chrome/browser/snapshots/lru_cache_unittest.mm b/ios/chrome/browser/snapshots/lru_cache_unittest.mm
new file mode 100644
index 0000000..858a5c3
--- /dev/null
+++ b/ios/chrome/browser/snapshots/lru_cache_unittest.mm
@@ -0,0 +1,73 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "base/mac/scoped_nsobject.h"
+#import "ios/chrome/browser/snapshots/lru_cache.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+@interface LRUCacheTestDelegate : NSObject<LRUCacheDelegate>
+
+@property(nonatomic, retain) id<NSObject> lastEvictedObject;
+@property(nonatomic, assign) NSInteger evictedObjectsCount;
+
+@end
+
+@implementation LRUCacheTestDelegate
+
+@synthesize lastEvictedObject = _lastEvictedObject;
+@synthesize evictedObjectsCount = _evictedObjectsCount;
+
+- (void)lruCacheWillEvictObject:(id<NSObject>)obj {
+  self.lastEvictedObject = obj;
+  ++_evictedObjectsCount;
+}
+
+@end
+
+namespace {
+
+TEST(LRUCacheTest, Basic) {
+  base::scoped_nsobject<LRUCache> cache([[LRUCache alloc] initWithCacheSize:3]);
+  base::scoped_nsobject<LRUCacheTestDelegate> delegate(
+      [[LRUCacheTestDelegate alloc] init]);
+  [cache setDelegate:delegate];
+
+  base::scoped_nsobject<NSString> value1(
+      [[NSString alloc] initWithString:@"Value 1"]);
+  base::scoped_nsobject<NSString> value2(
+      [[NSString alloc] initWithString:@"Value 2"]);
+  base::scoped_nsobject<NSString> value3(
+      [[NSString alloc] initWithString:@"Value 3"]);
+  base::scoped_nsobject<NSString> value4(
+      [[NSString alloc] initWithString:@"Value 4"]);
+
+  EXPECT_TRUE([cache count] == 0);
+  EXPECT_TRUE([cache isEmpty]);
+
+  [cache setObject:value1 forKey:@"VALUE 1"];
+  [cache setObject:value2 forKey:@"VALUE 2"];
+  [cache setObject:value3 forKey:@"VALUE 3"];
+  [cache setObject:value4 forKey:@"VALUE 4"];
+
+  EXPECT_TRUE([cache count] == 3);
+  EXPECT_TRUE([delegate evictedObjectsCount] == 1);
+  EXPECT_TRUE([delegate lastEvictedObject] == value1.get());
+
+  // Check LRU behaviour, the value least recently added value should have been
+  // evicted.
+  id value = [cache objectForKey:@"VALUE 1"];
+  EXPECT_TRUE(value == nil);
+
+  value = [cache objectForKey:@"VALUE 2"];
+  EXPECT_TRUE(value == value2.get());
+
+  // Removing a non existing key shouldn't do anything.
+  [cache removeObjectForKey:@"XXX"];
+  EXPECT_TRUE([cache count] == 3);
+
+  [cache removeAllObjects];
+  EXPECT_TRUE([cache isEmpty]);
+}
+
+}  // namespace
diff --git a/ios/chrome/browser/snapshots/snapshot_cache.h b/ios/chrome/browser/snapshots/snapshot_cache.h
index 6932726..28e2c47 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache.h
+++ b/ios/chrome/browser/snapshots/snapshot_cache.h
@@ -10,6 +10,7 @@
 #include "base/mac/objc_property_releaser.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/time/time.h"
+#import "ios/chrome/browser/snapshots/lru_cache.h"
 
 typedef void (^GreyBlock)(UIImage*);
 
@@ -23,6 +24,12 @@
   // Dictionary to hold color snapshots in memory. n.b. Color snapshots are not
   // kept in memory on tablets.
   base::scoped_nsobject<NSMutableDictionary> imageDictionary_;
+
+  // Cache to hold color snapshots in memory. n.b. Color snapshots are not
+  // kept in memory on tablets. It is used in place of the imageDictionary_ when
+  // the LRU cache snapshot experiment is enabled.
+  base::scoped_nsobject<LRUCache> lruCache_;
+
   // Temporary dictionary to hold grey snapshots for tablet side swipe. This
   // will be nil before -createGreyCache is called and after -removeGreyCache
   // is called.
@@ -90,4 +97,11 @@
 - (void)saveGreyInBackgroundForSessionID:(NSString*)sessionID;
 @end
 
+// Additionnal methods that should only be used for tests.
+@interface SnapshotCache (TestingAdditions)
+- (BOOL)hasImageInMemory:(NSString*)sessionID;
+- (BOOL)hasGreyImageInMemory:(NSString*)sessionID;
+- (NSUInteger)lruCacheMaxSize;
+@end
+
 #endif  // IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_CACHE_H_
diff --git a/ios/chrome/browser/snapshots/snapshot_cache.mm b/ios/chrome/browser/snapshots/snapshot_cache.mm
index c33bfe9..b76ba6ec 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache.mm
+++ b/ios/chrome/browser/snapshots/snapshot_cache.mm
@@ -17,6 +17,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/task_runner_util.h"
 #include "base/threading/thread_restrictions.h"
+#include "ios/chrome/browser/experimental_flags.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/web/public/web_thread.h"
@@ -51,6 +52,9 @@
 const CGFloat kJPEGImageQuality = 1.0;  // Highest quality. No compression.
 // Sequence token to make sure creation/deletion of snapshots don't overlap.
 const char kSequenceToken[] = "SnapshotCacheSequenceToken";
+// Maximum size in number of elements that the LRU cache can hold before
+// starting to evict elements.
+const NSUInteger kLRUCacheMaxCapacity = 6;
 
 // The paths of the images saved to disk, given a cache directory.
 base::FilePath FilePathForSessionID(NSString* sessionID,
@@ -141,10 +145,14 @@
     propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]);
 
     if (!IsIPadIdiom()) {
-      // TODO(jbbegue): In the case where the cache grows, it is expensive.
-      // Make sure this doesn't suck when there are more than ten tabs.
-      imageDictionary_.reset(
-          [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]);
+      if (experimental_flags::IsLRUSnapshotCacheEnabled()) {
+        lruCache_.reset(
+            [[LRUCache alloc] initWithCacheSize:kLRUCacheMaxCapacity]);
+      } else {
+        imageDictionary_.reset([[NSMutableDictionary alloc]
+            initWithCapacity:kCacheInitialCapacity]);
+      }
+
       [[NSNotificationCenter defaultCenter]
           addObserver:self
              selector:@selector(handleLowMemory)
@@ -204,7 +212,12 @@
   if (IsIPadIdiom() && !callback)
     return;
 
-  UIImage* img = [imageDictionary_ objectForKey:sessionID];
+  UIImage* img = nil;
+  if (lruCache_)
+    img = [lruCache_ objectForKey:sessionID];
+  else
+    img = [imageDictionary_ objectForKey:sessionID];
+
   if (img) {
     if (callback)
       callback(img);
@@ -223,8 +236,12 @@
         // The iPad tab switcher is currently using its own memory cache so the
         // image is not stored in memory here if running on iPad.
         // The same logic is used on image writes (code below).
-        if (!IsIPadIdiom() && image)
-          [imageDictionary_ setObject:image forKey:sessionID];
+        if (!IsIPadIdiom() && image) {
+          if (lruCache_)
+            [lruCache_ setObject:image forKey:sessionID];
+          else
+            [imageDictionary_ setObject:image forKey:sessionID];
+        }
         if (callback)
           callback(image);
       }));
@@ -239,7 +256,10 @@
   // is not stored in memory here if running on iPad.
   // The same logic is used on image reads (code above).
   if (!IsIPadIdiom()) {
-    [imageDictionary_ setObject:img forKey:sessionID];
+    if (lruCache_)
+      [lruCache_ setObject:img forKey:sessionID];
+    else
+      [imageDictionary_ setObject:img forKey:sessionID];
   }
   // Save the image to disk.
   web::WebThread::PostBlockingPoolSequencedTask(
@@ -253,7 +273,11 @@
 
 - (void)removeImageWithSessionID:(NSString*)sessionID {
   DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
-  [imageDictionary_ removeObjectForKey:sessionID];
+  if (lruCache_)
+    [lruCache_ removeObjectForKey:sessionID];
+  else
+    [imageDictionary_ removeObjectForKey:sessionID];
+
   web::WebThread::PostBlockingPoolSequencedTask(
       kSequenceToken, FROM_HERE,
       base::BindBlock(^{
@@ -354,8 +378,12 @@
   if (!sessionID)
     return;
   backgroundingImageSessionId_.reset([sessionID copy]);
-  backgroundingColorImage_.reset(
-      [[imageDictionary_ objectForKey:sessionID] retain]);
+  if (lruCache_) {
+    backgroundingColorImage_.reset([[lruCache_ objectForKey:sessionID] retain]);
+  } else {
+    backgroundingColorImage_.reset(
+        [[imageDictionary_ objectForKey:sessionID] retain]);
+  }
 }
 
 - (void)handleLowMemory {
@@ -364,17 +392,28 @@
   NSMutableDictionary* dictionary =
       [[NSMutableDictionary alloc] initWithCapacity:2];
   for (NSString* sessionID in pinnedIDs_) {
-    UIImage* image = [imageDictionary_ objectForKey:sessionID];
+    UIImage* image = nil;
+    if (lruCache_)
+      image = [lruCache_ objectForKey:sessionID];
+    else
+      image = [imageDictionary_ objectForKey:sessionID];
     if (image)
       [dictionary setObject:image forKey:sessionID];
   }
-  imageDictionary_.reset(dictionary);
+  if (lruCache_) {
+    [lruCache_ removeAllObjects];
+    for (NSString* sessionID in pinnedIDs_)
+      [lruCache_ setObject:dictionary[sessionID] forKey:sessionID];
+  } else {
+    imageDictionary_.reset(dictionary);
+  }
 }
 
 - (void)handleEnterBackground {
   DCHECK(!IsIPadIdiom());
   DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
   [imageDictionary_ removeAllObjects];
+  [lruCache_ removeAllObjects];
 }
 
 - (void)handleBecomeActive {
@@ -399,7 +438,12 @@
   // Don't call -retrieveImageForSessionID here because it caches the colored
   // image, which we don't need for the grey image cache. But if the image is
   // already in the cache, use it.
-  UIImage* img = [imageDictionary_ objectForKey:sessionID];
+  UIImage* img = nil;
+  if (lruCache_)
+    img = [lruCache_ objectForKey:sessionID];
+  else
+    img = [imageDictionary_ objectForKey:sessionID];
+
   base::PostTaskAndReplyWithResult(
       web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE_USER_BLOCKING)
           .get(),
@@ -520,3 +564,21 @@
 }
 
 @end
+
+@implementation SnapshotCache (TestingAdditions)
+
+- (BOOL)hasImageInMemory:(NSString*)sessionID {
+  if (experimental_flags::IsLRUSnapshotCacheEnabled())
+    return [lruCache_ objectForKey:sessionID] != nil;
+  else
+    return [imageDictionary_ objectForKey:sessionID] != nil;
+}
+- (BOOL)hasGreyImageInMemory:(NSString*)sessionID {
+  return [greyImageDictionary_ objectForKey:sessionID] != nil;
+}
+
+- (NSUInteger)lruCacheMaxSize {
+  return [lruCache_ maxCacheSize];
+}
+
+@end
diff --git a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
index c77a9ae..40189d4 100644
--- a/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
+++ b/ios/chrome/browser/snapshots/snapshot_cache_unittest.mm
@@ -16,6 +16,7 @@
 #include "base/run_loop.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/time/time.h"
+#include "ios/chrome/browser/experimental_flags.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
 #include "ios/web/public/web_thread.h"
@@ -33,20 +34,6 @@
 - (void)handleLowMemory;
 @end
 
-@interface SnapshotCache (TestingAdditions)
-- (BOOL)hasImageInMemory:(NSString*)sessionID;
-- (BOOL)hasGreyImageInMemory:(NSString*)sessionID;
-@end
-
-@implementation SnapshotCache (TestingAdditions)
-- (BOOL)hasImageInMemory:(NSString*)sessionID {
-  return [imageDictionary_ objectForKey:sessionID] != nil;
-}
-- (BOOL)hasGreyImageInMemory:(NSString*)sessionID {
-  return [greyImageDictionary_ objectForKey:sessionID] != nil;
-}
-@end
-
 namespace {
 
 class SnapshotCacheTest : public PlatformTest {
@@ -235,8 +222,12 @@
 
   SnapshotCache* cache = GetSnapshotCache();
 
+  NSUInteger expectedCacheSize = kSessionCount;
+  if (experimental_flags::IsLRUSnapshotCacheEnabled())
+    expectedCacheSize = MIN(kSessionCount, [cache lruCacheMaxSize]);
+
   // Put all images in the cache.
-  for (NSUInteger i = 0; i < kSessionCount; ++i) {
+  for (NSUInteger i = 0; i < expectedCacheSize; ++i) {
     UIImage* image = [testImages_ objectAtIndex:i];
     NSString* sessionID = [testSessions_ objectAtIndex:i];
     [cache setImage:image withSessionID:sessionID];
@@ -244,7 +235,7 @@
 
   // Get images back.
   __block NSUInteger numberOfCallbacks = 0;
-  for (NSUInteger i = 0; i < kSessionCount; ++i) {
+  for (NSUInteger i = 0; i < expectedCacheSize; ++i) {
     NSString* sessionID = [testSessions_ objectAtIndex:i];
     UIImage* expectedImage = [testImages_ objectAtIndex:i];
     EXPECT_TRUE(expectedImage != nil);
@@ -256,7 +247,7 @@
                               ++numberOfCallbacks;
                             }];
   }
-  EXPECT_EQ(kSessionCount, numberOfCallbacks);
+  EXPECT_EQ(expectedCacheSize, numberOfCallbacks);
 }
 
 // This test puts all the snapshots in the cache and flushes them to disk.
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp
index 0125a56..3981dcd 100644
--- a/ios/chrome/ios_chrome.gyp
+++ b/ios/chrome/ios_chrome.gyp
@@ -409,6 +409,8 @@
         'browser/signin/signin_manager_factory_observer.h',
         'browser/signin/signin_util.h',
         'browser/signin/signin_util.mm',
+        'browser/snapshots/lru_cache.h',
+        'browser/snapshots/lru_cache.mm',
         'browser/snapshots/snapshot_cache.h',
         'browser/snapshots/snapshot_cache.mm',
         'browser/snapshots/snapshot_manager.h',
diff --git a/ios/chrome/ios_chrome_tests.gyp b/ios/chrome/ios_chrome_tests.gyp
index 828d956..9afb267 100644
--- a/ios/chrome/ios_chrome_tests.gyp
+++ b/ios/chrome/ios_chrome_tests.gyp
@@ -58,6 +58,7 @@
         'browser/net/retryable_url_fetcher_unittest.mm',
         'browser/signin/chrome_identity_service_observer_bridge_unittest.mm',
         'browser/signin/gaia_auth_fetcher_ios_unittest.mm',
+        'browser/snapshots/lru_cache_unittest.mm',
         'browser/snapshots/snapshot_cache_unittest.mm',
         'browser/snapshots/snapshots_util_unittest.mm',
         'browser/translate/translate_service_ios_unittest.cc',
diff --git a/ios/chrome/today_extension/strings/resources/ios_today_extension_strings_no.xtb b/ios/chrome/today_extension/strings/resources/ios_today_extension_strings_no.xtb
index d8592023..a6823eb 100644
--- a/ios/chrome/today_extension/strings/resources/ios_today_extension_strings_no.xtb
+++ b/ios/chrome/today_extension/strings/resources/ios_today_extension_strings_no.xtb
@@ -5,7 +5,7 @@
 <translation id="1418775127135578229">Åpne den kopierte linken</translation>
 <translation id="1487576085940433465">BEGIN_LINKObjekter i nærheten kringkaster nettsiderEND_LINK. En Google-tjeneste brukes til å forbedre kvaliteten på disse resultatene.</translation>
 <translation id="2026797012398135445">Lås opp enheten din for å slå på.</translation>
-<translation id="2316129865977710310">Nei takk</translation>
+<translation id="2316129865977710310">Nei, takk</translation>
 <translation id="3435896845095436175">Slå på</translation>
 <translation id="4394049700291259645">Slå av</translation>
 <translation id="5301954838959518834">OK, skjønner</translation>
diff --git a/ios/web/net/crw_cert_verification_controller.mm b/ios/web/net/crw_cert_verification_controller.mm
index 716c31e3..42d3738 100644
--- a/ios/web/net/crw_cert_verification_controller.mm
+++ b/ios/web/net/crw_cert_verification_controller.mm
@@ -8,6 +8,8 @@
 #include "base/mac/bind_objc_block.h"
 #import "base/memory/ref_counted.h"
 #import "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/rand_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/threading/worker_pool.h"
 #include "ios/web/net/cert_verifier_block_adapter.h"
@@ -22,6 +24,30 @@
 
 namespace {
 
+// Enum for Web.CertVerifyAgreement UMA metric to report certificate
+// verification mismatch between SecTrust API and CertVerifier. SecTrust API is
+// used for making load/no-load decision and CertVerifier is used for getting
+// the reason of verification failure. It is expected that mismatches will
+// happen for those 2 approaches (e.g. SecTrust API accepts the cert but
+// CertVerifier rejects it). This metric helps to understand how common
+// mismatches are.
+// Note: This enum is used to back an UMA histogram, and should be treated as
+// append-only.
+enum CertVerifyAgreement {
+  // There is no mismach. Both SecTrust API and CertVerifier accepted this cert.
+  CERT_VERIFY_AGREEMENT_ACCEPTED_BY_BOTH = 0,
+  // There is no mismach. Both SecTrust API and CertVerifier rejected this cert.
+  CERT_VERIFY_AGREEMENT_REJECTED_BY_BOTH,
+  // SecTrust API accepted the cert, but CertVerifier rejected it (e.g. MDM cert
+  // or CertVerifier was more strict during verification), this mismach is
+  // expected to be common because of MDM certs.
+  CERT_VERIFY_AGREEMENT_ACCEPTED_ONLY_BY_IOS,
+  // SecTrust API rejected the cert, but CertVerifier accepted it. This mismatch
+  // is expected to be uncommon.
+  CERT_VERIFY_AGREEMENT_ACCEPTED_ONLY_BY_NSS,
+  CERT_VERIFY_AGREEMENT_COUNT,
+};
+
 // This class takes ownership of block and releases it on UI thread, even if
 // |BlockHolder| is destructed on a background thread.
 template <class T>
@@ -59,6 +85,9 @@
   T block_;
 };
 
+typedef scoped_refptr<BlockHolder<web::PolicyDecisionHandler>>
+    PolicyDecisionHandlerHolder;
+
 }  // namespace
 
 @interface CRWCertVerificationController () {
@@ -76,9 +105,33 @@
 // Cert verification flags. Must be used on IO Thread.
 @property(nonatomic, readonly) int certVerifyFlags;
 
+// Returns YES if CertVerifier should be run (even if SecTrust API considers
+// cert as valid) and Web.CertVerifyAgreement UMA metric should be reported.
+// The result of this method is random and undeterministic.
+- (BOOL)shouldReportCertVerifyAgreement;
+
+// Reports Web.CertVerifyAgreement UMA metric.
+- (void)reportUMAForCertVerifyAgreement:(CertVerifyAgreement)agreement;
+
 // Creates _certVerifier object on IO thread.
 - (void)createCertVerifier;
 
+// Decides the policy for the given |trust| which was rejected by iOS and the
+// given |host| and calls |handler| on completion.
+- (void)
+decideLoadPolicyForRejectedTrustResult:(SecTrustResultType)trustResult
+                           serverTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust
+                                  host:(NSString*)host
+                     completionHandler:(PolicyDecisionHandlerHolder)handler;
+
+// Decides the policy for the given |trust| which was accepted by iOS and the
+// given |host| and calls |handler| on completion.
+- (void)
+decideLoadPolicyForAcceptedTrustResult:(SecTrustResultType)trustResult
+                           serverTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust
+                                  host:(NSString*)host
+                     completionHandler:(PolicyDecisionHandlerHolder)handler;
+
 // Verifies the given |cert| for the given |host| using |net::CertVerifier| and
 // calls |completionHandler| on completion. This method can be called on any
 // thread. |completionHandler| cannot be null and will be called asynchronously
@@ -98,10 +151,10 @@
 // Returns cert accept policy for the given SecTrust result. |trustResult| must
 // not be for a valid cert. Must be called on IO thread.
 - (web::CertAcceptPolicy)
-    loadPolicyForBadTrustResult:(SecTrustResultType)trustResult
-             certVerifierResult:(net::CertVerifyResult)certVerifierResult
-                    serverTrust:(SecTrustRef)trust
-                           host:(NSString*)host;
+    loadPolicyForRejectedTrustResult:(SecTrustResultType)trustResult
+                  certVerifierResult:(net::CertVerifyResult)certVerifierResult
+                         serverTrust:(SecTrustRef)trust
+                                host:(NSString*)host;
 
 @end
 
@@ -146,7 +199,7 @@
   // Since |completionHandler| can potentially capture multiple thread unsafe
   // objects (like Web Controller) |completionHandler| itself should never be
   // released on background thread and |BlockHolder| ensures that.
-  __block scoped_refptr<BlockHolder<web::PolicyDecisionHandler>> handlerHolder(
+  __block PolicyDecisionHandlerHolder handlerHolder(
       new BlockHolder<web::PolicyDecisionHandler>(completionHandler));
   [self verifyTrust:trust
       completionHandler:^(SecTrustResultType trustResult, BOOL dispatched) {
@@ -161,42 +214,16 @@
 
         if (web::GetSecurityStyleFromTrustResult(trustResult) ==
             web::SECURITY_STYLE_AUTHENTICATED) {
-          // SecTrust API considers this cert as valid.
-          dispatch_async(dispatch_get_main_queue(), ^{
-            handlerHolder->call(web::CERT_ACCEPT_POLICY_ALLOW,
-                                net::CertStatus());
-          });
-          return;
+          [self decideLoadPolicyForAcceptedTrustResult:trustResult
+                                           serverTrust:trust
+                                                  host:host
+                                     completionHandler:handlerHolder];
+        } else {
+          [self decideLoadPolicyForRejectedTrustResult:trustResult
+                                           serverTrust:trust
+                                                  host:host
+                                     completionHandler:handlerHolder];
         }
-
-        // SecTrust API considers this cert as invalid. Check the reason and
-        // whether or not user has decided to proceed with this bad cert.
-        scoped_refptr<net::X509Certificate> cert(
-            web::CreateCertFromTrust(trust));
-        [self verifyCert:cert
-                      forHost:host
-            completionHandler:^(net::CertVerifyResult certVerifierResult,
-                                BOOL dispatched) {
-              if (!dispatched) {
-                // Cert verification task did not start.
-                dispatch_async(dispatch_get_main_queue(), ^{
-                  handlerHolder->call(
-                      web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR,
-                      net::CertStatus());
-                });
-                return;
-              }
-
-              web::CertAcceptPolicy policy =
-                  [self loadPolicyForBadTrustResult:trustResult
-                                 certVerifierResult:certVerifierResult
-                                        serverTrust:trust.get()
-                                               host:host];
-
-              dispatch_async(dispatch_get_main_queue(), ^{
-                handlerHolder->call(policy, certVerifierResult.cert_status);
-              });
-            }];
       }];
 }
 
@@ -234,8 +261,6 @@
         // Retrieve the net::CertStatus for invalid certificates to determine
         // the rejection reason, it is possible that rejection reason could not
         // be determined and |cert_status| will be empty.
-        // TODO(eugenebut): Add UMA for CertVerifier and SecTrust verification
-        // mismatch (crbug.com/535699).
         scoped_refptr<net::X509Certificate> cert(
             web::CreateCertFromTrust(trust));
         [self verifyCert:cert
@@ -295,6 +320,17 @@
   return config.GetCertVerifyFlags();
 }
 
+- (BOOL)shouldReportCertVerifyAgreement {
+  // Cert verification is an expensive operation. Since extra verification will
+  // be used only for UMA reporting purposes, do that only for 1% of cases.
+  return base::RandGenerator(100) == 0;
+}
+
+- (void)reportUMAForCertVerifyAgreement:(CertVerifyAgreement)agreement {
+  UMA_HISTOGRAM_ENUMERATION("Web.CertVerifyAgreement", agreement,
+                            CERT_VERIFY_AGREEMENT_COUNT);
+}
+
 - (void)createCertVerifier {
   web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, base::BindBlock(^{
     net::URLRequestContext* context = _contextGetter->GetURLRequestContext();
@@ -303,6 +339,80 @@
   }));
 }
 
+- (void)
+decideLoadPolicyForRejectedTrustResult:(SecTrustResultType)trustResult
+                           serverTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust
+                                  host:(NSString*)host
+                     completionHandler:(PolicyDecisionHandlerHolder)handler {
+  // SecTrust API considers this cert as invalid. Check the reason and
+  // whether or not user has decided to proceed with this bad cert.
+  scoped_refptr<net::X509Certificate> cert(web::CreateCertFromTrust(trust));
+  [self verifyCert:cert
+                forHost:host
+      completionHandler:^(net::CertVerifyResult certVerifierResult,
+                          BOOL dispatched) {
+        if (!dispatched) {
+          // Cert verification task did not start.
+          dispatch_async(dispatch_get_main_queue(), ^{
+            handler->call(web::CERT_ACCEPT_POLICY_NON_RECOVERABLE_ERROR,
+                          net::CertStatus());
+          });
+          return;
+        }
+
+        web::CertAcceptPolicy policy =
+            [self loadPolicyForRejectedTrustResult:trustResult
+                                certVerifierResult:certVerifierResult
+                                       serverTrust:trust.get()
+                                              host:host];
+
+        dispatch_async(dispatch_get_main_queue(), ^{
+          if ([self shouldReportCertVerifyAgreement]) {
+            CertVerifyAgreement agreement =
+                net::IsCertStatusError(certVerifierResult.cert_status)
+                    ? CERT_VERIFY_AGREEMENT_REJECTED_BY_BOTH
+                    : CERT_VERIFY_AGREEMENT_ACCEPTED_ONLY_BY_NSS;
+            [self reportUMAForCertVerifyAgreement:agreement];
+          }
+          handler->call(policy, certVerifierResult.cert_status);
+        });
+      }];
+}
+
+- (void)
+decideLoadPolicyForAcceptedTrustResult:(SecTrustResultType)trustResult
+                           serverTrust:(base::ScopedCFTypeRef<SecTrustRef>)trust
+                                  host:(NSString*)host
+                     completionHandler:(PolicyDecisionHandlerHolder)handler {
+  // SecTrust API considers this cert as valid.
+  dispatch_async(dispatch_get_main_queue(), ^{
+    handler->call(web::CERT_ACCEPT_POLICY_ALLOW, net::CertStatus());
+  });
+
+  if ([self shouldReportCertVerifyAgreement]) {
+    // Execute CertVerifier::Verify to collect CertVerifyAgreement UMA.
+    scoped_refptr<net::X509Certificate> cert(web::CreateCertFromTrust(trust));
+    [self verifyCert:cert
+                  forHost:host
+        completionHandler:^(net::CertVerifyResult certVerifierResult,
+                            BOOL dispatched) {
+          if (!dispatched) {
+            return;
+          }
+          // SecTrust API accepted this cert and |PolicyDecisionHandler| has
+          // been called already. |CertVerifier| verification is executed only
+          // to collect CertVerifyAgreement UMA.
+          dispatch_async(dispatch_get_main_queue(), ^{
+            CertVerifyAgreement agreement =
+                net::IsCertStatusError(certVerifierResult.cert_status)
+                    ? CERT_VERIFY_AGREEMENT_ACCEPTED_ONLY_BY_IOS
+                    : CERT_VERIFY_AGREEMENT_ACCEPTED_BY_BOTH;
+            [self reportUMAForCertVerifyAgreement:agreement];
+          });
+        }];
+  }
+}
+
 - (void)verifyCert:(const scoped_refptr<net::X509Certificate>&)cert
               forHost:(NSString*)host
     completionHandler:(void (^)(net::CertVerifyResult, BOOL))completionHandler {
@@ -351,10 +461,10 @@
 }
 
 - (web::CertAcceptPolicy)
-    loadPolicyForBadTrustResult:(SecTrustResultType)trustResult
-             certVerifierResult:(net::CertVerifyResult)certVerifierResult
-                    serverTrust:(SecTrustRef)trust
-                           host:(NSString*)host {
+    loadPolicyForRejectedTrustResult:(SecTrustResultType)trustResult
+                  certVerifierResult:(net::CertVerifyResult)certVerifierResult
+                         serverTrust:(SecTrustRef)trust
+                                host:(NSString*)host {
   DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::IO);
   DCHECK_NE(web::SECURITY_STYLE_AUTHENTICATED,
             web::GetSecurityStyleFromTrustResult(trustResult));
diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
index 65c232e..d85fdb7 100644
--- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
+++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
@@ -962,16 +962,17 @@
     if (leafCert) {
       auto error = _certVerificationErrors->Get(
           {leafCert, base::SysNSStringToUTF8(host)});
-      if (error != _certVerificationErrors->end()) {
+      bool cacheHit = error != _certVerificationErrors->end();
+      if (cacheHit) {
         status.cert_status = error->second.status;
         recoverable = error->second.is_recoverable;
-      } else {
-        // TODO(eugenebut): Report UMA with cache size (crbug.com/541736).
       }
+      UMA_HISTOGRAM_BOOLEAN("WebController.CertVerificationErrorsCacheHit",
+                            cacheHit);
     }
   }
 
-  // Present SSL interstitial.
+  // Present SSL interstitial and inform everyone that the load is cancelled.
   [self.delegate presentSSLError:info
                     forSSLStatus:status
                      recoverable:recoverable
@@ -985,6 +986,7 @@
                             [self loadCurrentURL];
                           }
                         }];
+  [self loadCancelled];
 }
 #endif  // #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
 
diff --git a/ipc/ipc_channel_reader.cc b/ipc/ipc_channel_reader.cc
index 335852f..e0cb2bf 100644
--- a/ipc/ipc_channel_reader.cc
+++ b/ipc/ipc_channel_reader.cc
@@ -122,7 +122,8 @@
       0;
 
   // Save any partial data in the overflow buffer.
-  input_overflow_buf_.assign(p, end - p);
+  if (p != input_overflow_buf_.data())
+    input_overflow_buf_.assign(p, end - p);
 
   if (!input_overflow_buf_.empty()) {
     // We have something in the overflow buffer, which means that we will
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 514d40f..a7dac69 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -167,8 +167,6 @@
     "cdm/aes_decryptor.h",
     "cdm/cdm_adapter.cc",
     "cdm/cdm_adapter.h",
-    "cdm/cdm_adapter_impl.cc",
-    "cdm/cdm_adapter_impl.h",
     "cdm/default_cdm_factory.cc",
     "cdm/default_cdm_factory.h",
     "cdm/json_web_key.cc",
diff --git a/media/audio/sounds/audio_stream_handler.cc b/media/audio/sounds/audio_stream_handler.cc
index 28758b23..5f175ea 100644
--- a/media/audio/sounds/audio_stream_handler.cc
+++ b/media/audio/sounds/audio_stream_handler.cc
@@ -124,6 +124,9 @@
 
   void OnError(AudioOutputStream* /* stream */) override {
     LOG(ERROR) << "Error during system sound reproduction.";
+    AudioManager::Get()->GetTaskRunner()->PostTask(
+        FROM_HERE,
+        base::Bind(&AudioStreamContainer::Stop, base::Unretained(this)));
   }
 
   void StopStream() {
diff --git a/media/cast/sender/external_video_encoder.cc b/media/cast/sender/external_video_encoder.cc
index 31b483957..196b16e2 100644
--- a/media/cast/sender/external_video_encoder.cc
+++ b/media/cast/sender/external_video_encoder.cc
@@ -308,7 +308,8 @@
 
         const char kZeroEncodeDetails[] = "zero-encode-details";
         const std::string details = base::StringPrintf(
-            "%c/%c,id=%" PRIu32 ",rtp=%" PRIu32 ",br=%d,q=%zu,act=%c,ref=%d",
+            ("%c/%c,id=%" PRIu32 ",rtp=%" PRIu32 ",br=%d,q=%" PRIuS
+             ",act=%c,ref=%d"),
             codec_profile_ == media::VP8PROFILE_ANY ? 'V' : 'H',
             key_frame ? 'K' : 'D', encoded_frame->frame_id,
             encoded_frame->rtp_timestamp, request.target_bit_rate / 1000,
diff --git a/media/cdm/cdm_adapter.cc b/media/cdm/cdm_adapter.cc
index 94791cf0..0e9fc16b 100644
--- a/media/cdm/cdm_adapter.cc
+++ b/media/cdm/cdm_adapter.cc
@@ -4,16 +4,155 @@
 
 #include "media/cdm/cdm_adapter.h"
 
+#include "base/bind.h"
 #include "base/logging.h"
-#include "media/cdm/cdm_adapter_impl.h"
+#include "base/message_loop/message_loop.h"
+#include "base/stl_util.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "media/base/cdm_context.h"
+#include "media/base/cdm_initialized_promise.h"
+#include "media/base/cdm_key_information.h"
+#include "media/base/limits.h"
+#include "media/cdm/cdm_wrapper.h"
 
 namespace media {
 
-CdmAdapter::CdmAdapter() {}
+namespace {
 
-CdmAdapter::~CdmAdapter() {}
+cdm::SessionType MediaSessionTypeToCdmSessionType(
+    MediaKeys::SessionType session_type) {
+  switch (session_type) {
+    case MediaKeys::TEMPORARY_SESSION:
+      return cdm::kTemporary;
+    case MediaKeys::PERSISTENT_LICENSE_SESSION:
+      return cdm::kPersistentLicense;
+    case MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION:
+      return cdm::kPersistentKeyRelease;
+  }
 
-void CdmAdapter::Initialize(
+  NOTREACHED();
+  return cdm::kTemporary;
+}
+
+cdm::InitDataType MediaInitDataTypeToCdmInitDataType(
+    EmeInitDataType init_data_type) {
+  switch (init_data_type) {
+    case EmeInitDataType::CENC:
+      return cdm::kCenc;
+    case EmeInitDataType::KEYIDS:
+      return cdm::kKeyIds;
+    case EmeInitDataType::WEBM:
+      return cdm::kWebM;
+    case EmeInitDataType::UNKNOWN:
+      break;
+  }
+
+  NOTREACHED();
+  return cdm::kKeyIds;
+}
+
+MediaKeys::Exception CdmErrorTypeToMediaExceptionType(cdm::Error error) {
+  switch (error) {
+    case cdm::kNotSupportedError:
+      return MediaKeys::NOT_SUPPORTED_ERROR;
+    case cdm::kInvalidStateError:
+      return MediaKeys::INVALID_STATE_ERROR;
+    case cdm::kInvalidAccessError:
+      return MediaKeys::INVALID_ACCESS_ERROR;
+    case cdm::kQuotaExceededError:
+      return MediaKeys::QUOTA_EXCEEDED_ERROR;
+    case cdm::kUnknownError:
+      return MediaKeys::UNKNOWN_ERROR;
+    case cdm::kClientError:
+      return MediaKeys::CLIENT_ERROR;
+    case cdm::kOutputError:
+      return MediaKeys::OUTPUT_ERROR;
+  }
+
+  NOTREACHED();
+  return MediaKeys::UNKNOWN_ERROR;
+}
+
+MediaKeys::MessageType CdmMessageTypeToMediaMessageType(
+    cdm::MessageType message_type) {
+  switch (message_type) {
+    case cdm::kLicenseRequest:
+      return MediaKeys::LICENSE_REQUEST;
+    case cdm::kLicenseRenewal:
+      return MediaKeys::LICENSE_RENEWAL;
+    case cdm::kLicenseRelease:
+      return MediaKeys::LICENSE_RELEASE;
+  }
+
+  NOTREACHED();
+  return MediaKeys::LICENSE_REQUEST;
+}
+
+CdmKeyInformation::KeyStatus CdmKeyStatusToCdmKeyInformationKeyStatus(
+    cdm::KeyStatus status) {
+  switch (status) {
+    case cdm::kUsable:
+      return CdmKeyInformation::USABLE;
+    case cdm::kInternalError:
+      return CdmKeyInformation::INTERNAL_ERROR;
+    case cdm::kExpired:
+      return CdmKeyInformation::EXPIRED;
+    case cdm::kOutputRestricted:
+      return CdmKeyInformation::OUTPUT_RESTRICTED;
+    case cdm::kOutputDownscaled:
+      return CdmKeyInformation::OUTPUT_DOWNSCALED;
+    case cdm::kStatusPending:
+      return CdmKeyInformation::KEY_STATUS_PENDING;
+    case cdm::kReleased:
+      return CdmKeyInformation::RELEASED;
+  }
+
+  NOTREACHED();
+  return CdmKeyInformation::INTERNAL_ERROR;
+}
+
+static void* GetCdmHost(int host_interface_version, void* user_data) {
+  if (!host_interface_version || !user_data)
+    return nullptr;
+
+  static_assert(
+      cdm::ContentDecryptionModule::Host::kVersion == cdm::Host_8::kVersion,
+      "update the code below");
+
+  // Ensure IsSupportedCdmHostVersion matches implementation of this function.
+  // Always update this DCHECK when updating this function.
+  // If this check fails, update this function and DCHECK or update
+  // IsSupportedCdmHostVersion.
+
+  DCHECK(
+      // Future version is not supported.
+      !IsSupportedCdmHostVersion(cdm::Host_8::kVersion + 1) &&
+      // Current version is supported.
+      IsSupportedCdmHostVersion(cdm::Host_8::kVersion) &&
+      // Include all previous supported versions (if any) here.
+      IsSupportedCdmHostVersion(cdm::Host_7::kVersion) &&
+      // One older than the oldest supported version is not supported.
+      !IsSupportedCdmHostVersion(cdm::Host_7::kVersion - 1));
+  DCHECK(IsSupportedCdmHostVersion(host_interface_version));
+
+  CdmAdapter* cdm_adapter = static_cast<CdmAdapter*>(user_data);
+  DVLOG(1) << "Create CDM Host with version " << host_interface_version;
+  switch (host_interface_version) {
+    case cdm::Host_8::kVersion:
+      return static_cast<cdm::Host_8*>(cdm_adapter);
+    case cdm::Host_7::kVersion:
+      return static_cast<cdm::Host_7*>(cdm_adapter);
+    default:
+      NOTREACHED();
+      return nullptr;
+  }
+}
+
+}  // namespace
+
+// static
+void CdmAdapter::Create(
     const std::string& key_system,
     const base::FilePath& cdm_path,
     const CdmConfig& cdm_config,
@@ -22,7 +161,7 @@
     const LegacySessionErrorCB& legacy_session_error_cb,
     const SessionKeysChangeCB& session_keys_change_cb,
     const SessionExpirationUpdateCB& session_expiration_update_cb,
-    scoped_ptr<SimpleCdmPromise> promise) {
+    const CdmCreatedCB& cdm_created_cb) {
   DCHECK(!key_system.empty());
   DCHECK(!session_message_cb.is_null());
   DCHECK(!session_closed_cb.is_null());
@@ -30,18 +169,103 @@
   DCHECK(!session_keys_change_cb.is_null());
   DCHECK(!session_expiration_update_cb.is_null());
 
-  scoped_refptr<CdmAdapterImpl> cdm = new CdmAdapterImpl();
-  cdm->Initialize(key_system, cdm_path, cdm_config, session_message_cb,
-                  session_closed_cb, legacy_session_error_cb,
-                  session_keys_change_cb, session_expiration_update_cb,
-                  promise.Pass());
-  cdm_ = cdm.Pass();
+  scoped_refptr<CdmAdapter> cdm =
+      new CdmAdapter(key_system, cdm_config, session_message_cb,
+                     session_closed_cb, legacy_session_error_cb,
+                     session_keys_change_cb, session_expiration_update_cb);
+
+  // |cdm| ownership passed to the promise.
+  scoped_ptr<CdmInitializedPromise> cdm_created_promise(
+      new CdmInitializedPromise(cdm_created_cb, cdm));
+
+  cdm->Initialize(cdm_path, cdm_created_promise.Pass());
+}
+
+CdmAdapter::CdmAdapter(
+    const std::string& key_system,
+    const CdmConfig& cdm_config,
+    const SessionMessageCB& session_message_cb,
+    const SessionClosedCB& session_closed_cb,
+    const LegacySessionErrorCB& legacy_session_error_cb,
+    const SessionKeysChangeCB& session_keys_change_cb,
+    const SessionExpirationUpdateCB& session_expiration_update_cb)
+    : key_system_(key_system),
+      cdm_config_(cdm_config),
+      session_message_cb_(session_message_cb),
+      session_closed_cb_(session_closed_cb),
+      legacy_session_error_cb_(legacy_session_error_cb),
+      session_keys_change_cb_(session_keys_change_cb),
+      session_expiration_update_cb_(session_expiration_update_cb),
+      task_runner_(base::ThreadTaskRunnerHandle::Get()),
+      weak_factory_(this) {
+  DCHECK(!key_system_.empty());
+  DCHECK(!session_message_cb_.is_null());
+  DCHECK(!session_closed_cb_.is_null());
+  DCHECK(!legacy_session_error_cb_.is_null());
+  DCHECK(!session_keys_change_cb_.is_null());
+  DCHECK(!session_expiration_update_cb_.is_null());
+}
+
+CdmAdapter::~CdmAdapter() {}
+
+CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system,
+                                          const base::FilePath& cdm_path) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // TODO(jrummell): We need to call INITIALIZE_CDM_MODULE() and
+  // DeinitializeCdmModule(). However, that should only be done once for the
+  // library.
+  base::NativeLibraryLoadError error;
+  library_.Reset(base::LoadNativeLibrary(cdm_path, &error));
+  if (!library_.is_valid()) {
+    DVLOG(1) << "CDM instance for " + key_system + " could not be created. "
+             << error.ToString();
+    return nullptr;
+  }
+
+  CreateCdmFunc create_cdm_func = reinterpret_cast<CreateCdmFunc>(
+      library_.GetFunctionPointer("CreateCdmInstance"));
+  if (!create_cdm_func) {
+    DVLOG(1) << "No CreateCdmInstance() in library for " + key_system;
+    return nullptr;
+  }
+
+  CdmWrapper* cdm = CdmWrapper::Create(create_cdm_func, key_system.data(),
+                                       key_system.size(), GetCdmHost, this);
+
+  DVLOG(1) << "CDM instance for " + key_system + (cdm ? "" : " could not be") +
+                  " created.";
+  return cdm;
+}
+
+void CdmAdapter::Initialize(const base::FilePath& cdm_path,
+                            scoped_ptr<media::SimpleCdmPromise> promise) {
+  cdm_.reset(CreateCdmInstance(key_system_, cdm_path));
+  if (!cdm_) {
+    promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0,
+                    "Unable to create CDM.");
+    return;
+  }
+
+  cdm_->Initialize(cdm_config_.allow_distinctive_identifier,
+                   cdm_config_.allow_persistent_state);
+  promise->resolve();
 }
 
 void CdmAdapter::SetServerCertificate(const std::vector<uint8_t>& certificate,
                                       scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(cdm_);
-  cdm_->SetServerCertificate(certificate, promise.Pass());
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  if (certificate.size() < limits::kMinCertificateLength ||
+      certificate.size() > limits::kMaxCertificateLength) {
+    promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0,
+                    "Incorrect certificate.");
+    return;
+  }
+
+  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+  cdm_->SetServerCertificate(promise_id, vector_as_array(&certificate),
+                             certificate.size());
 }
 
 void CdmAdapter::CreateSessionAndGenerateRequest(
@@ -49,45 +273,234 @@
     EmeInitDataType init_data_type,
     const std::vector<uint8_t>& init_data,
     scoped_ptr<NewSessionCdmPromise> promise) {
-  DCHECK(cdm_);
-  return cdm_->CreateSessionAndGenerateRequest(session_type, init_data_type,
-                                               init_data, promise.Pass());
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+  cdm_->CreateSessionAndGenerateRequest(
+      promise_id, MediaSessionTypeToCdmSessionType(session_type),
+      MediaInitDataTypeToCdmInitDataType(init_data_type),
+      vector_as_array(&init_data), init_data.size());
 }
 
 void CdmAdapter::LoadSession(SessionType session_type,
                              const std::string& session_id,
                              scoped_ptr<NewSessionCdmPromise> promise) {
-  DCHECK(cdm_);
-  DCHECK(!session_id.empty());
-  return cdm_->LoadSession(session_type, session_id, promise.Pass());
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+  cdm_->LoadSession(promise_id, MediaSessionTypeToCdmSessionType(session_type),
+                    session_id.data(), session_id.size());
 }
 
 void CdmAdapter::UpdateSession(const std::string& session_id,
                                const std::vector<uint8_t>& response,
                                scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(cdm_);
+  DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(!session_id.empty());
   DCHECK(!response.empty());
-  return cdm_->UpdateSession(session_id, response, promise.Pass());
+
+  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+  cdm_->UpdateSession(promise_id, session_id.data(), session_id.size(),
+                      vector_as_array(&response), response.size());
 }
 
 void CdmAdapter::CloseSession(const std::string& session_id,
                               scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(cdm_);
+  DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(!session_id.empty());
-  return cdm_->CloseSession(session_id, promise.Pass());
+
+  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+  cdm_->CloseSession(promise_id, session_id.data(), session_id.size());
 }
 
 void CdmAdapter::RemoveSession(const std::string& session_id,
                                scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(cdm_);
+  DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(!session_id.empty());
-  return cdm_->RemoveSession(session_id, promise.Pass());
+
+  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+  cdm_->RemoveSession(promise_id, session_id.data(), session_id.size());
 }
 
 CdmContext* CdmAdapter::GetCdmContext() {
-  DCHECK(cdm_);
-  return cdm_->GetCdmContext();
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // TODO(jrummell): Support the Decryptor interface.
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+cdm::Buffer* CdmAdapter::Allocate(uint32_t capacity) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // TODO(jrummell): Figure out how memory should be passed around when
+  // decrypting.
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void CdmAdapter::SetTimer(int64_t delay_ms, void* context) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  task_runner_->PostDelayedTask(FROM_HERE,
+                                base::Bind(&CdmAdapter::TimerExpired,
+                                           weak_factory_.GetWeakPtr(), context),
+                                base::TimeDelta::FromMilliseconds(delay_ms));
+}
+
+void CdmAdapter::TimerExpired(void* context) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  cdm_->TimerExpired(context);
+}
+
+cdm::Time CdmAdapter::GetCurrentWallTime() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  return base::Time::Now().ToDoubleT();
+}
+
+void CdmAdapter::OnResolvePromise(uint32_t promise_id) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  cdm_promise_adapter_.ResolvePromise(promise_id);
+}
+
+void CdmAdapter::OnResolveNewSessionPromise(uint32_t promise_id,
+                                            const char* session_id,
+                                            uint32_t session_id_size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  cdm_promise_adapter_.ResolvePromise(promise_id,
+                                      std::string(session_id, session_id_size));
+}
+
+void CdmAdapter::OnRejectPromise(uint32_t promise_id,
+                                 cdm::Error error,
+                                 uint32_t system_code,
+                                 const char* error_message,
+                                 uint32_t error_message_size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  cdm_promise_adapter_.RejectPromise(
+      promise_id, CdmErrorTypeToMediaExceptionType(error), system_code,
+      std::string(error_message, error_message_size));
+}
+
+void CdmAdapter::OnSessionMessage(const char* session_id,
+                                  uint32_t session_id_size,
+                                  cdm::MessageType message_type,
+                                  const char* message,
+                                  uint32_t message_size,
+                                  const char* legacy_destination_url,
+                                  uint32_t legacy_destination_url_size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(legacy_destination_url_size == 0 ||
+         message_type != cdm::MessageType::kLicenseRequest);
+
+  GURL verified_gurl =
+      GURL(std::string(legacy_destination_url, legacy_destination_url_size));
+  if (!verified_gurl.is_valid()) {
+    DLOG(WARNING) << "SessionMessage legacy_destination_url is invalid : "
+                  << verified_gurl.possibly_invalid_spec();
+    verified_gurl = GURL::EmptyGURL();  // Replace invalid destination_url.
+  }
+
+  const uint8_t* message_ptr = reinterpret_cast<const uint8*>(message);
+  session_message_cb_.Run(
+      std::string(session_id, session_id_size),
+      CdmMessageTypeToMediaMessageType(message_type),
+      std::vector<uint8_t>(message_ptr, message_ptr + message_size),
+      verified_gurl);
+}
+
+void CdmAdapter::OnSessionKeysChange(const char* session_id,
+                                     uint32_t session_id_size,
+                                     bool has_additional_usable_key,
+                                     const cdm::KeyInformation* keys_info,
+                                     uint32_t keys_info_count) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  CdmKeysInfo keys;
+  keys.reserve(keys_info_count);
+  for (uint32_t i = 0; i < keys_info_count; ++i) {
+    const auto& info = keys_info[i];
+    keys.push_back(new CdmKeyInformation(
+        info.key_id, info.key_id_size,
+        CdmKeyStatusToCdmKeyInformationKeyStatus(info.status),
+        info.system_code));
+  }
+
+  session_keys_change_cb_.Run(std::string(session_id, session_id_size),
+                              has_additional_usable_key, keys.Pass());
+}
+
+void CdmAdapter::OnExpirationChange(const char* session_id,
+                                    uint32_t session_id_size,
+                                    cdm::Time new_expiry_time) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  session_expiration_update_cb_.Run(std::string(session_id, session_id_size),
+                                    base::Time::FromDoubleT(new_expiry_time));
+}
+
+void CdmAdapter::OnSessionClosed(const char* session_id,
+                                 uint32_t session_id_size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  session_closed_cb_.Run(std::string(session_id, session_id_size));
+}
+
+void CdmAdapter::OnLegacySessionError(const char* session_id,
+                                      uint32_t session_id_size,
+                                      cdm::Error error,
+                                      uint32_t system_code,
+                                      const char* error_message,
+                                      uint32_t error_message_size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  legacy_session_error_cb_.Run(std::string(session_id, session_id_size),
+                               CdmErrorTypeToMediaExceptionType(error),
+                               system_code,
+                               std::string(error_message, error_message_size));
+}
+
+void CdmAdapter::SendPlatformChallenge(const char* service_id,
+                                       uint32_t service_id_size,
+                                       const char* challenge,
+                                       uint32_t challenge_size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // TODO(jrummell): If platform verification is available, use it.
+  NOTIMPLEMENTED();
+  cdm::PlatformChallengeResponse platform_challenge_response = {};
+  cdm_->OnPlatformChallengeResponse(platform_challenge_response);
+}
+
+void CdmAdapter::EnableOutputProtection(uint32_t desired_protection_mask) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // TODO(jrummell): If output protection is available, use it.
+  NOTIMPLEMENTED();
+}
+
+void CdmAdapter::QueryOutputProtectionStatus() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // TODO(jrummell): If output protection is available, use it.
+  NOTIMPLEMENTED();
+  cdm_->OnQueryOutputProtectionStatus(cdm::kQueryFailed, 0, 0);
+}
+
+void CdmAdapter::OnDeferredInitializationDone(cdm::StreamType stream_type,
+                                              cdm::Status decoder_status) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // Not initializing a decoder, so this should never happen.
+  NOTREACHED();
+}
+
+// The CDM owns the returned object and must call FileIO::Close() to release it.
+cdm::FileIO* CdmAdapter::CreateFileIO(cdm::FileIOClient* client) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // TODO(jrummell): This should use the mojo FileIO client.
+  NOTIMPLEMENTED();
+  return nullptr;
 }
 
 }  // namespace media
diff --git a/media/cdm/cdm_adapter.h b/media/cdm/cdm_adapter.h
index b304fb3..59c31ad 100644
--- a/media/cdm/cdm_adapter.h
+++ b/media/cdm/cdm_adapter.h
@@ -8,34 +8,42 @@
 #include <string>
 #include <vector>
 
+#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/scoped_native_library.h"
+#include "base/threading/thread.h"
 #include "media/base/cdm_config.h"
+#include "media/base/cdm_factory.h"
+#include "media/base/cdm_promise_adapter.h"
 #include "media/base/media_export.h"
 #include "media/base/media_keys.h"
+#include "media/cdm/api/content_decryption_module.h"
 
 namespace media {
 
-// Due to windows warning C4275 (should not export a class that inherits from
-// a non-exported class), this class exists as a wrapper for CdmAdapterImpl.
-class MEDIA_EXPORT CdmAdapter : public MediaKeys {
- public:
-  CdmAdapter();
+class CdmWrapper;
 
-  // Load the CDM using |cdm_path| and initialize it using |key_system| and
+class MEDIA_EXPORT CdmAdapter : public MediaKeys,
+                                NON_EXPORTED_BASE(public cdm::Host_7),
+                                NON_EXPORTED_BASE(public cdm::Host_8) {
+ public:
+  // Create the CDM using |cdm_path| and initialize it using |key_system| and
   // |cdm_config|. Callbacks will be used for events generated by the CDM.
-  // |promise| is resolved if the CDM is loaded and initialized correctly,
-  // otherwise it is rejected.
-  void Initialize(const std::string& key_system,
-                  const base::FilePath& cdm_path,
-                  const CdmConfig& cdm_config,
-                  const SessionMessageCB& session_message_cb,
-                  const SessionClosedCB& session_closed_cb,
-                  const LegacySessionErrorCB& legacy_session_error_cb,
-                  const SessionKeysChangeCB& session_keys_change_cb,
-                  const SessionExpirationUpdateCB& session_expiration_update_cb,
-                  scoped_ptr<SimpleCdmPromise> promise);
+  // |cdm_created_cb| will be called when the CDM is loaded and initialized.
+  static void Create(
+      const std::string& key_system,
+      const base::FilePath& cdm_path,
+      const CdmConfig& cdm_config,
+      const SessionMessageCB& session_message_cb,
+      const SessionClosedCB& session_closed_cb,
+      const LegacySessionErrorCB& legacy_session_error_cb,
+      const SessionKeysChangeCB& session_keys_change_cb,
+      const SessionExpirationUpdateCB& session_expiration_update_cb,
+      const CdmCreatedCB& cdm_created_cb);
 
   // MediaKeys implementation.
   void SetServerCertificate(const std::vector<uint8_t>& certificate,
@@ -57,10 +65,99 @@
                      scoped_ptr<SimpleCdmPromise> promise) override;
   CdmContext* GetCdmContext() override;
 
+  // cdm::Host_7 and cdm::Host_8 implementation.
+  cdm::Buffer* Allocate(uint32_t capacity) override;
+  void SetTimer(int64_t delay_ms, void* context) override;
+  cdm::Time GetCurrentWallTime() override;
+  void OnResolveNewSessionPromise(uint32_t promise_id,
+                                  const char* session_id,
+                                  uint32_t session_id_size) override;
+  void OnResolvePromise(uint32_t promise_id) override;
+  void OnRejectPromise(uint32_t promise_id,
+                       cdm::Error error,
+                       uint32_t system_code,
+                       const char* error_message,
+                       uint32_t error_message_size) override;
+  void OnSessionMessage(const char* session_id,
+                        uint32_t session_id_size,
+                        cdm::MessageType message_type,
+                        const char* message,
+                        uint32_t message_size,
+                        const char* legacy_destination_url,
+                        uint32_t legacy_destination_url_size) override;
+  void OnSessionKeysChange(const char* session_id,
+                           uint32_t session_id_size,
+                           bool has_additional_usable_key,
+                           const cdm::KeyInformation* keys_info,
+                           uint32_t keys_info_count) override;
+  void OnExpirationChange(const char* session_id,
+                          uint32_t session_id_size,
+                          cdm::Time new_expiry_time) override;
+  void OnSessionClosed(const char* session_id,
+                       uint32_t session_id_size) override;
+  void OnLegacySessionError(const char* session_id,
+                            uint32_t session_id_size,
+                            cdm::Error error,
+                            uint32_t system_code,
+                            const char* error_message,
+                            uint32_t error_message_size) override;
+  void SendPlatformChallenge(const char* service_id,
+                             uint32_t service_id_size,
+                             const char* challenge,
+                             uint32_t challenge_size) override;
+  void EnableOutputProtection(uint32_t desired_protection_mask) override;
+  void QueryOutputProtectionStatus() override;
+  void OnDeferredInitializationDone(cdm::StreamType stream_type,
+                                    cdm::Status decoder_status) override;
+  cdm::FileIO* CreateFileIO(cdm::FileIOClient* client) override;
+
  private:
+  CdmAdapter(const std::string& key_system,
+             const CdmConfig& cdm_config,
+             const SessionMessageCB& session_message_cb,
+             const SessionClosedCB& session_closed_cb,
+             const LegacySessionErrorCB& legacy_session_error_cb,
+             const SessionKeysChangeCB& session_keys_change_cb,
+             const SessionExpirationUpdateCB& session_expiration_update_cb);
   ~CdmAdapter() final;
 
-  scoped_refptr<MediaKeys> cdm_;
+  // Load the CDM using |cdm_path| and initialize it. |promise| is resolved if
+  // the CDM is successfully loaded and initialized, rejected otherwise.
+  void Initialize(const base::FilePath& cdm_path,
+                  scoped_ptr<media::SimpleCdmPromise> promise);
+
+  // Create an instance of the |key_system| CDM contained in |cdm_path|.
+  // Caller owns the returned pointer. On error (unable to load, does not
+  // support |key_system|, does not support an supported interface, etc.)
+  // NULL will be returned.
+  CdmWrapper* CreateCdmInstance(const std::string& key_system,
+                                const base::FilePath& cdm_path);
+
+  // Helper for SetTimer().
+  void TimerExpired(void* context);
+
+  // Keep a reference to the CDM.
+  base::ScopedNativeLibrary library_;
+
+  // Used to keep track of promises while the CDM is processing the request.
+  CdmPromiseAdapter cdm_promise_adapter_;
+
+  scoped_ptr<CdmWrapper> cdm_;
+  std::string key_system_;
+  CdmConfig cdm_config_;
+
+  // Callbacks for firing session events.
+  SessionMessageCB session_message_cb_;
+  SessionClosedCB session_closed_cb_;
+  LegacySessionErrorCB legacy_session_error_cb_;
+  SessionKeysChangeCB session_keys_change_cb_;
+  SessionExpirationUpdateCB session_expiration_update_cb_;
+
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+  // NOTE: Weak pointers must be invalidated before all other member variables.
+  base::WeakPtrFactory<CdmAdapter> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(CdmAdapter);
 };
 
diff --git a/media/cdm/cdm_adapter_impl.cc b/media/cdm/cdm_adapter_impl.cc
deleted file mode 100644
index aabd1fa8..0000000
--- a/media/cdm/cdm_adapter_impl.cc
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/cdm/cdm_adapter_impl.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/stl_util.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "media/base/cdm_context.h"
-#include "media/base/cdm_key_information.h"
-#include "media/base/limits.h"
-#include "media/cdm/cdm_wrapper.h"
-
-namespace media {
-
-namespace {
-
-cdm::SessionType MediaSessionTypeToCdmSessionType(
-    MediaKeys::SessionType session_type) {
-  switch (session_type) {
-    case MediaKeys::TEMPORARY_SESSION:
-      return cdm::kTemporary;
-    case MediaKeys::PERSISTENT_LICENSE_SESSION:
-      return cdm::kPersistentLicense;
-    case MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION:
-      return cdm::kPersistentKeyRelease;
-  }
-
-  NOTREACHED();
-  return cdm::kTemporary;
-}
-
-cdm::InitDataType MediaInitDataTypeToCdmInitDataType(
-    EmeInitDataType init_data_type) {
-  switch (init_data_type) {
-    case EmeInitDataType::CENC:
-      return cdm::kCenc;
-    case EmeInitDataType::KEYIDS:
-      return cdm::kKeyIds;
-    case EmeInitDataType::WEBM:
-      return cdm::kWebM;
-    case EmeInitDataType::UNKNOWN:
-      break;
-  }
-
-  NOTREACHED();
-  return cdm::kKeyIds;
-}
-
-MediaKeys::Exception CdmErrorTypeToMediaExceptionType(cdm::Error error) {
-  switch (error) {
-    case cdm::kNotSupportedError:
-      return MediaKeys::NOT_SUPPORTED_ERROR;
-    case cdm::kInvalidStateError:
-      return MediaKeys::INVALID_STATE_ERROR;
-    case cdm::kInvalidAccessError:
-      return MediaKeys::INVALID_ACCESS_ERROR;
-    case cdm::kQuotaExceededError:
-      return MediaKeys::QUOTA_EXCEEDED_ERROR;
-    case cdm::kUnknownError:
-      return MediaKeys::UNKNOWN_ERROR;
-    case cdm::kClientError:
-      return MediaKeys::CLIENT_ERROR;
-    case cdm::kOutputError:
-      return MediaKeys::OUTPUT_ERROR;
-  }
-
-  NOTREACHED();
-  return MediaKeys::UNKNOWN_ERROR;
-}
-
-MediaKeys::MessageType CdmMessageTypeToMediaMessageType(
-    cdm::MessageType message_type) {
-  switch (message_type) {
-    case cdm::kLicenseRequest:
-      return MediaKeys::LICENSE_REQUEST;
-    case cdm::kLicenseRenewal:
-      return MediaKeys::LICENSE_RENEWAL;
-    case cdm::kLicenseRelease:
-      return MediaKeys::LICENSE_RELEASE;
-  }
-
-  NOTREACHED();
-  return MediaKeys::LICENSE_REQUEST;
-}
-
-CdmKeyInformation::KeyStatus CdmKeyStatusToCdmKeyInformationKeyStatus(
-    cdm::KeyStatus status) {
-  switch (status) {
-    case cdm::kUsable:
-      return CdmKeyInformation::USABLE;
-    case cdm::kInternalError:
-      return CdmKeyInformation::INTERNAL_ERROR;
-    case cdm::kExpired:
-      return CdmKeyInformation::EXPIRED;
-    case cdm::kOutputRestricted:
-      return CdmKeyInformation::OUTPUT_RESTRICTED;
-    case cdm::kOutputDownscaled:
-      return CdmKeyInformation::OUTPUT_DOWNSCALED;
-    case cdm::kStatusPending:
-      return CdmKeyInformation::KEY_STATUS_PENDING;
-    case cdm::kReleased:
-      return CdmKeyInformation::RELEASED;
-  }
-
-  NOTREACHED();
-  return CdmKeyInformation::INTERNAL_ERROR;
-}
-
-static void* GetCdmHost(int host_interface_version, void* user_data) {
-  if (!host_interface_version || !user_data)
-    return nullptr;
-
-  static_assert(
-      cdm::ContentDecryptionModule::Host::kVersion == cdm::Host_8::kVersion,
-      "update the code below");
-
-  // Ensure IsSupportedCdmHostVersion matches implementation of this function.
-  // Always update this DCHECK when updating this function.
-  // If this check fails, update this function and DCHECK or update
-  // IsSupportedCdmHostVersion.
-
-  DCHECK(
-      // Future version is not supported.
-      !IsSupportedCdmHostVersion(cdm::Host_8::kVersion + 1) &&
-      // Current version is supported.
-      IsSupportedCdmHostVersion(cdm::Host_8::kVersion) &&
-      // Include all previous supported versions (if any) here.
-      IsSupportedCdmHostVersion(cdm::Host_7::kVersion) &&
-      // One older than the oldest supported version is not supported.
-      !IsSupportedCdmHostVersion(cdm::Host_7::kVersion - 1));
-  DCHECK(IsSupportedCdmHostVersion(host_interface_version));
-
-  CdmAdapterImpl* cdm_adapter = static_cast<CdmAdapterImpl*>(user_data);
-  DVLOG(1) << "Create CDM Host with version " << host_interface_version;
-  switch (host_interface_version) {
-    case cdm::Host_8::kVersion:
-      return static_cast<cdm::Host_8*>(cdm_adapter);
-    case cdm::Host_7::kVersion:
-      return static_cast<cdm::Host_7*>(cdm_adapter);
-    default:
-      NOTREACHED();
-      return nullptr;
-  }
-}
-
-}  // namespace
-
-CdmAdapterImpl::CdmAdapterImpl()
-    : task_runner_(base::ThreadTaskRunnerHandle::Get()), weak_factory_(this) {}
-
-CdmAdapterImpl::~CdmAdapterImpl() {}
-
-CdmWrapper* CdmAdapterImpl::CreateCdmInstance(const std::string& key_system,
-                                              const base::FilePath& cdm_path) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  // TODO(jrummell): We need to call INITIALIZE_CDM_MODULE() and
-  // DeinitializeCdmModule(). However, that should only be done once for the
-  // library.
-  base::NativeLibraryLoadError error;
-  library_.Reset(base::LoadNativeLibrary(cdm_path, &error));
-  if (!library_.is_valid()) {
-    DVLOG(1) << "CDM instance for " + key_system + " could not be created. "
-             << error.ToString();
-    return nullptr;
-  }
-
-  CreateCdmFunc create_cdm_func = reinterpret_cast<CreateCdmFunc>(
-      library_.GetFunctionPointer("CreateCdmInstance"));
-  if (!create_cdm_func) {
-    DVLOG(1) << "No CreateCdmInstance() in library for " + key_system;
-    return nullptr;
-  }
-
-  CdmWrapper* cdm = CdmWrapper::Create(create_cdm_func, key_system.data(),
-                                       key_system.size(), GetCdmHost, this);
-
-  DVLOG(1) << "CDM instance for " + key_system + (cdm ? "" : " could not be") +
-                  " created.";
-  return cdm;
-}
-
-void CdmAdapterImpl::Initialize(
-    const std::string& key_system,
-    const base::FilePath& cdm_path,
-    const CdmConfig& cdm_config,
-    const SessionMessageCB& session_message_cb,
-    const SessionClosedCB& session_closed_cb,
-    const LegacySessionErrorCB& legacy_session_error_cb,
-    const SessionKeysChangeCB& session_keys_change_cb,
-    const SessionExpirationUpdateCB& session_expiration_update_cb,
-    scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(!key_system.empty());
-  DCHECK(key_system_.empty());
-  DCHECK(!session_message_cb.is_null());
-  DCHECK(!session_closed_cb.is_null());
-  DCHECK(!legacy_session_error_cb.is_null());
-  DCHECK(!session_keys_change_cb.is_null());
-  DCHECK(!session_expiration_update_cb.is_null());
-
-  session_message_cb_ = session_message_cb;
-  session_closed_cb_ = session_closed_cb;
-  legacy_session_error_cb_ = legacy_session_error_cb;
-  session_keys_change_cb_ = session_keys_change_cb;
-  session_expiration_update_cb_ = session_expiration_update_cb;
-
-  cdm_.reset(CreateCdmInstance(key_system, cdm_path));
-  if (!cdm_) {
-    promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0,
-                    "Unable to create CDM.");
-    return;
-  }
-
-  key_system_ = key_system;
-  cdm_config_ = cdm_config;
-  cdm_->Initialize(cdm_config_.allow_distinctive_identifier,
-                   cdm_config_.allow_persistent_state);
-  promise->resolve();
-}
-
-void CdmAdapterImpl::SetServerCertificate(
-    const std::vector<uint8_t>& certificate,
-    scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  if (certificate.size() < limits::kMinCertificateLength ||
-      certificate.size() > limits::kMaxCertificateLength) {
-    promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0,
-                    "Incorrect certificate.");
-    return;
-  }
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
-  cdm_->SetServerCertificate(promise_id, vector_as_array(&certificate),
-                             certificate.size());
-}
-
-void CdmAdapterImpl::CreateSessionAndGenerateRequest(
-    SessionType session_type,
-    EmeInitDataType init_data_type,
-    const std::vector<uint8_t>& init_data,
-    scoped_ptr<NewSessionCdmPromise> promise) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
-  cdm_->CreateSessionAndGenerateRequest(
-      promise_id, MediaSessionTypeToCdmSessionType(session_type),
-      MediaInitDataTypeToCdmInitDataType(init_data_type),
-      vector_as_array(&init_data), init_data.size());
-}
-
-void CdmAdapterImpl::LoadSession(SessionType session_type,
-                                 const std::string& session_id,
-                                 scoped_ptr<NewSessionCdmPromise> promise) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
-  cdm_->LoadSession(promise_id, MediaSessionTypeToCdmSessionType(session_type),
-                    session_id.data(), session_id.size());
-}
-
-void CdmAdapterImpl::UpdateSession(const std::string& session_id,
-                                   const std::vector<uint8_t>& response,
-                                   scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(!session_id.empty());
-  DCHECK(!response.empty());
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
-  cdm_->UpdateSession(promise_id, session_id.data(), session_id.size(),
-                      vector_as_array(&response), response.size());
-}
-
-void CdmAdapterImpl::CloseSession(const std::string& session_id,
-                                  scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(!session_id.empty());
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
-  cdm_->CloseSession(promise_id, session_id.data(), session_id.size());
-}
-
-void CdmAdapterImpl::RemoveSession(const std::string& session_id,
-                                   scoped_ptr<SimpleCdmPromise> promise) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(!session_id.empty());
-
-  uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
-  cdm_->RemoveSession(promise_id, session_id.data(), session_id.size());
-}
-
-CdmContext* CdmAdapterImpl::GetCdmContext() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  // TODO(jrummell): Support the Decryptor interface.
-  NOTIMPLEMENTED();
-  return nullptr;
-}
-
-cdm::Buffer* CdmAdapterImpl::Allocate(uint32_t capacity) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  // TODO(jrummell): Figure out how memory should be passed around when
-  // decrypting.
-  NOTIMPLEMENTED();
-  return nullptr;
-}
-
-void CdmAdapterImpl::SetTimer(int64_t delay_ms, void* context) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  task_runner_->PostDelayedTask(FROM_HERE,
-                                base::Bind(&CdmAdapterImpl::TimerExpired,
-                                           weak_factory_.GetWeakPtr(), context),
-                                base::TimeDelta::FromMilliseconds(delay_ms));
-}
-
-void CdmAdapterImpl::TimerExpired(void* context) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  cdm_->TimerExpired(context);
-}
-
-cdm::Time CdmAdapterImpl::GetCurrentWallTime() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  return base::Time::Now().ToDoubleT();
-}
-
-void CdmAdapterImpl::OnResolvePromise(uint32_t promise_id) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  cdm_promise_adapter_.ResolvePromise(promise_id);
-}
-
-void CdmAdapterImpl::OnResolveNewSessionPromise(uint32_t promise_id,
-                                                const char* session_id,
-                                                uint32_t session_id_size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  cdm_promise_adapter_.ResolvePromise(promise_id,
-                                      std::string(session_id, session_id_size));
-}
-
-void CdmAdapterImpl::OnRejectPromise(uint32_t promise_id,
-                                     cdm::Error error,
-                                     uint32_t system_code,
-                                     const char* error_message,
-                                     uint32_t error_message_size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  cdm_promise_adapter_.RejectPromise(
-      promise_id, CdmErrorTypeToMediaExceptionType(error), system_code,
-      std::string(error_message, error_message_size));
-}
-
-void CdmAdapterImpl::OnSessionMessage(const char* session_id,
-                                      uint32_t session_id_size,
-                                      cdm::MessageType message_type,
-                                      const char* message,
-                                      uint32_t message_size,
-                                      const char* legacy_destination_url,
-                                      uint32_t legacy_destination_url_size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(legacy_destination_url_size == 0 ||
-         message_type != cdm::MessageType::kLicenseRequest);
-
-  GURL verified_gurl =
-      GURL(std::string(legacy_destination_url, legacy_destination_url_size));
-  if (!verified_gurl.is_valid()) {
-    DLOG(WARNING) << "SessionMessage legacy_destination_url is invalid : "
-                  << verified_gurl.possibly_invalid_spec();
-    verified_gurl = GURL::EmptyGURL();  // Replace invalid destination_url.
-  }
-
-  const uint8_t* message_ptr = reinterpret_cast<const uint8*>(message);
-  session_message_cb_.Run(
-      std::string(session_id, session_id_size),
-      CdmMessageTypeToMediaMessageType(message_type),
-      std::vector<uint8_t>(message_ptr, message_ptr + message_size),
-      verified_gurl);
-}
-
-void CdmAdapterImpl::OnSessionKeysChange(const char* session_id,
-                                         uint32_t session_id_size,
-                                         bool has_additional_usable_key,
-                                         const cdm::KeyInformation* keys_info,
-                                         uint32_t keys_info_count) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  CdmKeysInfo keys;
-  keys.reserve(keys_info_count);
-  for (uint32_t i = 0; i < keys_info_count; ++i) {
-    const auto& info = keys_info[i];
-    keys.push_back(new CdmKeyInformation(
-        info.key_id, info.key_id_size,
-        CdmKeyStatusToCdmKeyInformationKeyStatus(info.status),
-        info.system_code));
-  }
-
-  session_keys_change_cb_.Run(std::string(session_id, session_id_size),
-                              has_additional_usable_key, keys.Pass());
-}
-
-void CdmAdapterImpl::OnExpirationChange(const char* session_id,
-                                        uint32_t session_id_size,
-                                        cdm::Time new_expiry_time) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  session_expiration_update_cb_.Run(std::string(session_id, session_id_size),
-                                    base::Time::FromDoubleT(new_expiry_time));
-}
-
-void CdmAdapterImpl::OnSessionClosed(const char* session_id,
-                                     uint32_t session_id_size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  session_closed_cb_.Run(std::string(session_id, session_id_size));
-}
-
-void CdmAdapterImpl::OnLegacySessionError(const char* session_id,
-                                          uint32_t session_id_size,
-                                          cdm::Error error,
-                                          uint32_t system_code,
-                                          const char* error_message,
-                                          uint32_t error_message_size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  legacy_session_error_cb_.Run(std::string(session_id, session_id_size),
-                               CdmErrorTypeToMediaExceptionType(error),
-                               system_code,
-                               std::string(error_message, error_message_size));
-}
-
-void CdmAdapterImpl::SendPlatformChallenge(const char* service_id,
-                                           uint32_t service_id_size,
-                                           const char* challenge,
-                                           uint32_t challenge_size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  // TODO(jrummell): If platform verification is available, use it.
-  NOTIMPLEMENTED();
-  cdm::PlatformChallengeResponse platform_challenge_response = {};
-  cdm_->OnPlatformChallengeResponse(platform_challenge_response);
-}
-
-void CdmAdapterImpl::EnableOutputProtection(uint32_t desired_protection_mask) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  // TODO(jrummell): If output protection is available, use it.
-  NOTIMPLEMENTED();
-}
-
-void CdmAdapterImpl::QueryOutputProtectionStatus() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  // TODO(jrummell): If output protection is available, use it.
-  NOTIMPLEMENTED();
-  cdm_->OnQueryOutputProtectionStatus(cdm::kQueryFailed, 0, 0);
-}
-
-void CdmAdapterImpl::OnDeferredInitializationDone(cdm::StreamType stream_type,
-                                                  cdm::Status decoder_status) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  // Not initializing a decoder, so this should never happen.
-  NOTREACHED();
-}
-
-// The CDM owns the returned object and must call FileIO::Close() to release it.
-cdm::FileIO* CdmAdapterImpl::CreateFileIO(cdm::FileIOClient* client) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-
-  // TODO(jrummell): This should use the mojo FileIO client.
-  NOTIMPLEMENTED();
-  return nullptr;
-}
-
-}  // namespace media
diff --git a/media/cdm/cdm_adapter_impl.h b/media/cdm/cdm_adapter_impl.h
deleted file mode 100644
index 41b091c..0000000
--- a/media/cdm/cdm_adapter_impl.h
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_CDM_CDM_ADAPTER_IMPL_H_
-#define MEDIA_CDM_CDM_ADAPTER_IMPL_H_
-
-#include <string>
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/scoped_native_library.h"
-#include "base/threading/thread.h"
-#include "media/base/cdm_config.h"
-#include "media/base/cdm_promise_adapter.h"
-#include "media/base/media_keys.h"
-#include "media/cdm/api/content_decryption_module.h"
-
-namespace media {
-
-class CdmWrapper;
-
-class CdmAdapterImpl : public MediaKeys,
-                       public cdm::Host_7,
-                       public cdm::Host_8 {
- public:
-  CdmAdapterImpl();
-
-  // Load the CDM using |cdm_path| and initialize it using |key_system| and
-  // |cdm_config|. Callbacks will be used for events generated by the CDM.
-  // |promise| is resolved if the CDM is loaded and initialized correctly,
-  // otherwise it is rejected.
-  void Initialize(const std::string& key_system,
-                  const base::FilePath& cdm_path,
-                  const CdmConfig& cdm_config,
-                  const SessionMessageCB& session_message_cb,
-                  const SessionClosedCB& session_closed_cb,
-                  const LegacySessionErrorCB& legacy_session_error_cb,
-                  const SessionKeysChangeCB& session_keys_change_cb,
-                  const SessionExpirationUpdateCB& session_expiration_update_cb,
-                  scoped_ptr<SimpleCdmPromise> promise);
-
-  // MediaKeys implementation.
-  void SetServerCertificate(const std::vector<uint8_t>& certificate,
-                            scoped_ptr<SimpleCdmPromise> promise) override;
-  void CreateSessionAndGenerateRequest(
-      SessionType session_type,
-      EmeInitDataType init_data_type,
-      const std::vector<uint8_t>& init_data,
-      scoped_ptr<NewSessionCdmPromise> promise) override;
-  void LoadSession(SessionType session_type,
-                   const std::string& session_id,
-                   scoped_ptr<NewSessionCdmPromise> promise) override;
-  void UpdateSession(const std::string& session_id,
-                     const std::vector<uint8_t>& response,
-                     scoped_ptr<SimpleCdmPromise> promise) override;
-  void CloseSession(const std::string& session_id,
-                    scoped_ptr<SimpleCdmPromise> promise) override;
-  void RemoveSession(const std::string& session_id,
-                     scoped_ptr<SimpleCdmPromise> promise) override;
-  CdmContext* GetCdmContext() override;
-
-  // cdm::Host_7 and cdm::Host_8 implementation.
-  cdm::Buffer* Allocate(uint32_t capacity) override;
-  void SetTimer(int64_t delay_ms, void* context) override;
-  cdm::Time GetCurrentWallTime() override;
-  void OnResolveNewSessionPromise(uint32_t promise_id,
-                                  const char* session_id,
-                                  uint32_t session_id_size) override;
-  void OnResolvePromise(uint32_t promise_id) override;
-  void OnRejectPromise(uint32_t promise_id,
-                       cdm::Error error,
-                       uint32_t system_code,
-                       const char* error_message,
-                       uint32_t error_message_size) override;
-  void OnSessionMessage(const char* session_id,
-                        uint32_t session_id_size,
-                        cdm::MessageType message_type,
-                        const char* message,
-                        uint32_t message_size,
-                        const char* legacy_destination_url,
-                        uint32_t legacy_destination_url_size) override;
-  void OnSessionKeysChange(const char* session_id,
-                           uint32_t session_id_size,
-                           bool has_additional_usable_key,
-                           const cdm::KeyInformation* keys_info,
-                           uint32_t keys_info_count) override;
-  void OnExpirationChange(const char* session_id,
-                          uint32_t session_id_size,
-                          cdm::Time new_expiry_time) override;
-  void OnSessionClosed(const char* session_id,
-                       uint32_t session_id_size) override;
-  void OnLegacySessionError(const char* session_id,
-                            uint32_t session_id_size,
-                            cdm::Error error,
-                            uint32_t system_code,
-                            const char* error_message,
-                            uint32_t error_message_size) override;
-  void SendPlatformChallenge(const char* service_id,
-                             uint32_t service_id_size,
-                             const char* challenge,
-                             uint32_t challenge_size) override;
-  void EnableOutputProtection(uint32_t desired_protection_mask) override;
-  void QueryOutputProtectionStatus() override;
-  void OnDeferredInitializationDone(cdm::StreamType stream_type,
-                                    cdm::Status decoder_status) override;
-  cdm::FileIO* CreateFileIO(cdm::FileIOClient* client) override;
-
- private:
-  ~CdmAdapterImpl() final;
-
-  // Create an instance of the |key_system| CDM contained in |cdm_path|.
-  // Caller owns the returned pointer. On error (unable to load, does not
-  // support |key_system|, does not support an supported interface, etc.)
-  // NULL will be returned.
-  CdmWrapper* CreateCdmInstance(const std::string& key_system,
-                                const base::FilePath& cdm_path);
-
-  // Helper for SetTimer().
-  void TimerExpired(void* context);
-
-  // Keep a reference to the CDM.
-  base::ScopedNativeLibrary library_;
-
-  // Used to keep track of promises while the CDM is processing the request.
-  CdmPromiseAdapter cdm_promise_adapter_;
-
-  scoped_ptr<CdmWrapper> cdm_;
-  std::string key_system_;
-  CdmConfig cdm_config_;
-
-  // Callbacks for firing session events.
-  SessionMessageCB session_message_cb_;
-  SessionClosedCB session_closed_cb_;
-  LegacySessionErrorCB legacy_session_error_cb_;
-  SessionKeysChangeCB session_keys_change_cb_;
-  SessionExpirationUpdateCB session_expiration_update_cb_;
-
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
-  // NOTE: Weak pointers must be invalidated before all other member variables.
-  base::WeakPtrFactory<CdmAdapterImpl> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CdmAdapterImpl);
-};
-
-}  // namespace media
-
-#endif  // MEDIA_CDM_CDM_ADAPTER_IMPL_H_
diff --git a/media/media.gyp b/media/media.gyp
index 75f6e91..2ca6e550 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -490,8 +490,6 @@
         'cdm/aes_decryptor.h',
         'cdm/cdm_adapter.cc',
         'cdm/cdm_adapter.h',
-        'cdm/cdm_adapter_impl.cc',
-        'cdm/cdm_adapter_impl.h',
         'cdm/default_cdm_factory.cc',
         'cdm/default_cdm_factory.h',
         'cdm/json_web_key.cc',
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc
index cad8463..4b23aad 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -183,7 +183,7 @@
   switch (format) {
     case PIXEL_FORMAT_I420:
       DCHECK_LE(plane, 2u);
-      return GL_R8_EXT;
+      return GL_RED_EXT;
     case PIXEL_FORMAT_NV12:
       DCHECK_LE(plane, 1u);
       DLOG(WARNING) << "NV12 format not supported yet";
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index ddd5f8d..a2dbd16 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -956,13 +956,6 @@
 }
 
 // static
-bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) {
-  PreloadResult result;
-  return DecodeHSTSPreload(host, &result) && result.has_pins &&
-         kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts;
-}
-
-// static
 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
   PreloadResult result;
   if (!DecodeHSTSPreload(host, &result) ||
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index d7befb7..554326a8 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -307,14 +307,6 @@
                                    const HostPortPair& host_port_pair,
                                    const SSLInfo& ssl_info);
 
-  // Returns true iff we have any static public key pins for the |host| and
-  // iff its set of required pins is the set we expect for Google
-  // properties.
-  //
-  // If |host| matches both an exact entry and is a subdomain of another
-  // entry, the exact match determines the return value.
-  static bool IsGooglePinnedProperty(const std::string& host);
-
   // The maximum number of seconds for which we'll cache an HSTS request.
   static const long int kMaxHSTSAgeSecs;
 
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 96d6231..21160fbd 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -1162,69 +1162,6 @@
   EXPECT_TRUE(state.ShouldUpgradeToSSL("www.google.com"));
 }
 
-TEST_F(TransportSecurityStateTest, GooglePinnedProperties) {
-  EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
-      "www.example.com"));
-  EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
-      "www.paypal.com"));
-  EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
-      "mail.twitter.com"));
-  EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
-      "www.google.com.int"));
-  EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
-      "jottit.com"));
-  // learn.doubleclick.net has a more specific match than
-  // *.doubleclick.com, and has 0 or NULL for its required certs.
-  // This test ensures that the exact-match-preferred behavior
-  // works.
-  EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
-      "learn.doubleclick.net"));
-
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "encrypted.google.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "mail.google.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "accounts.google.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "doubleclick.net"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "ad.doubleclick.net"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "youtube.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "www.profiles.google.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "checkout.google.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "googleadservices.com"));
-
-  EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
-      "www.example.com"));
-  EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
-      "www.paypal.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "checkout.google.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "googleadservices.com"));
-
-  // Test some SNI hosts:
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "gmail.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "googlegroups.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "www.googlegroups.com"));
-
-  // These hosts used to only be HSTS when SNI was available.
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "gmail.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "googlegroups.com"));
-  EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
-      "www.googlegroups.com"));
-}
-
 TEST_F(TransportSecurityStateTest, HPKPReporting) {
   HostPortPair host_port_pair(kHost, kPort);
   HostPortPair subdomain_host_port_pair(kSubdomain, kPort);
@@ -1446,14 +1383,13 @@
   MockCertificateReportSender mock_report_sender;
   state.SetReportSender(&mock_report_sender);
 
-  ASSERT_TRUE(
-      TransportSecurityState::IsGooglePinnedProperty(kPreloadedPinDomain));
   EnableStaticPins(&state);
 
   TransportSecurityState::PKPState pkp_state;
   TransportSecurityState::STSState unused_sts_state;
   ASSERT_TRUE(state.GetStaticDomainState(kPreloadedPinDomain, &unused_sts_state,
                                          &pkp_state));
+  ASSERT_TRUE(pkp_state.HasPublicKeyPins());
 
   GURL report_uri = pkp_state.report_uri;
   ASSERT_TRUE(report_uri.is_valid());
diff --git a/net/net.gypi b/net/net.gypi
index dd96f5e0..6b56678 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -54,6 +54,9 @@
       'base/rand_callback.h',
       'base/registry_controlled_domains/registry_controlled_domain.cc',
       'base/registry_controlled_domains/registry_controlled_domain.h',
+      'base/socket_performance_watcher.cc',
+      'base/socket_performance_watcher.h',
+      'base/socket_performance_watcher_factory.h',
       'base/sys_addrinfo.h',
       'base/url_util.cc',
       'base/url_util.h',
@@ -510,9 +513,6 @@
       'base/sdch_observer.h',
       'base/sdch_problem_code_list.h',
       'base/sdch_problem_codes.h',
-      'base/socket_performance_watcher.cc',
-      'base/socket_performance_watcher.h',
-      'base/socket_performance_watcher_factory.h',
       'base/static_cookie_policy.cc',
       'base/static_cookie_policy.h',
       'base/test_data_stream.cc',
diff --git a/pdf/pdf.cc b/pdf/pdf.cc
index 1f580e4f..9521fdf 100644
--- a/pdf/pdf.cc
+++ b/pdf/pdf.cc
@@ -10,8 +10,6 @@
 
 #include "base/command_line.h"
 #include "base/logging.h"
-#include "gin/array_buffer.h"
-#include "gin/public/isolate_holder.h"
 #include "pdf/out_of_process_instance.h"
 #include "ppapi/c/ppp.h"
 #include "ppapi/cpp/private/internal_module.h"
@@ -24,14 +22,6 @@
 
 bool g_sdk_initialized_via_pepper = false;
 
-gin::IsolateHolder* g_isolate_holder = nullptr;
-
-void TearDownV8() {
-  g_isolate_holder->isolate()->Exit();
-  delete g_isolate_holder;
-  g_isolate_holder = nullptr;
-}
-
 }  // namespace
 
 PDFModule::PDFModule() {
@@ -39,7 +29,6 @@
 
 PDFModule::~PDFModule() {
   if (g_sdk_initialized_via_pepper) {
-    TearDownV8();
     chrome_pdf::ShutdownSDK();
     g_sdk_initialized_via_pepper = false;
   }
@@ -60,15 +49,8 @@
       v8::V8::SetNativesDataBlob(&natives);
       v8::V8::SetSnapshotDataBlob(&snapshot);
     }
-    gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
-                                   gin::ArrayBufferAllocator::SharedInstance());
-    g_isolate_holder =
-        new gin::IsolateHolder(gin::IsolateHolder::kSingleThread);
-    g_isolate_holder->isolate()->Enter();
-    if (!chrome_pdf::InitializeSDK()) {
-      TearDownV8();
+    if (!chrome_pdf::InitializeSDK())
       return NULL;
-    }
     g_sdk_initialized_via_pepper = true;
   }
 
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index 8631088..d23c141 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -18,7 +18,9 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "gin/array_buffer.h"
 #include "gin/public/gin_embedders.h"
+#include "gin/public/isolate_holder.h"
 #include "pdf/draw_utils.h"
 #include "pdf/pdfium/pdfium_api_string_buffer_adapter.h"
 #include "pdf/pdfium/pdfium_mem_buffer_file_read.h"
@@ -449,9 +451,27 @@
   return base::UTF16ToUTF8(value);
 }
 
+gin::IsolateHolder* g_isolate_holder = nullptr;
+
+void SetUpV8() {
+  gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
+                                 gin::ArrayBufferAllocator::SharedInstance());
+  g_isolate_holder =
+      new gin::IsolateHolder(gin::IsolateHolder::kSingleThread);
+  g_isolate_holder->isolate()->Enter();
+}
+
+void TearDownV8() {
+  g_isolate_holder->isolate()->Exit();
+  delete g_isolate_holder;
+  g_isolate_holder = nullptr;
+}
+
 }  // namespace
 
 bool InitializeSDK() {
+  SetUpV8();
+
   FPDF_LIBRARY_CONFIG config;
   config.version = 2;
   config.m_pUserFontPaths = nullptr;
@@ -470,6 +490,7 @@
 }
 
 void ShutdownSDK() {
+  TearDownV8();
   FPDF_DestroyLibrary();
 }
 
diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc
index 5df3145..adcea09 100644
--- a/ppapi/proxy/ppb_image_data_proxy.cc
+++ b/ppapi/proxy/ppb_image_data_proxy.cc
@@ -387,16 +387,16 @@
 
 void* PlatformImageData::Map() {
   if (!mapped_canvas_.get()) {
+    const bool is_opaque = false;
     mapped_canvas_.reset(transport_dib_->GetPlatformCanvas(desc_.size.width,
-                                                           desc_.size.height));
+                                                           desc_.size.height,
+                                                           is_opaque));
     if (!mapped_canvas_.get())
       return NULL;
   }
-  const SkBitmap& bitmap =
-      skia::GetTopDevice(*mapped_canvas_)->accessBitmap(true);
-
-  bitmap.lockPixels();
-  return bitmap.getAddr(0, 0);
+  SkPixmap pixmap;
+  skia::GetWritablePixels(mapped_canvas_.get(), &pixmap);
+  return pixmap.writable_addr();
 }
 
 void PlatformImageData::Unmap() {
diff --git a/ppapi/tests/test_view.cc b/ppapi/tests/test_view.cc
index 8239b03..f8c20d87 100644
--- a/ppapi/tests/test_view.cc
+++ b/ppapi/tests/test_view.cc
@@ -142,8 +142,8 @@
 
   // Original clip should be the full frame.
   pp::Rect original_clip = last_view_.GetClipRect();
-  ASSERT_TRUE(original_clip.x() == 0);
-  ASSERT_TRUE(original_clip.y() == 0);
+  ASSERT_TRUE(original_clip.x() == 1);
+  ASSERT_TRUE(original_clip.y() == 1);
   ASSERT_TRUE(original_clip.width() == original_rect.width());
   ASSERT_TRUE(original_clip.height() == original_rect.height());
 
@@ -164,8 +164,9 @@
   instance_->EvalScript(script_stream.str());
 
   pp::Rect desired_clip = original_clip;
-  desired_clip.set_y(clip_amount);
-  desired_clip.set_height(desired_clip.height() - desired_clip.y());
+  desired_clip.set_y(clip_amount + original_clip.y());
+  desired_clip.set_height(
+    desired_clip.height() - desired_clip.y() +  original_clip.y());
 
   while (WaitUntilViewChanged() && last_view_.GetClipRect() != desired_clip) {
   }
diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc
index bb22792..1e7a7d1 100644
--- a/printing/pdf_metafile_skia.cc
+++ b/printing/pdf_metafile_skia.cc
@@ -10,6 +10,7 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/time/time.h"
+#include "printing/print_settings.h"
 #include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkData.h"
 #include "third_party/skia/include/core/SkDocument.h"
@@ -163,7 +164,11 @@
     pdf_doc->endPage();
   }
   SkTArray<SkDocument::Attribute> info;
-  info.emplace_back(SkString("Creator"), SkString("Chromium"));
+  const std::string& user_agent = GetAgent();
+  info.emplace_back(SkString("Creator"),
+                    user_agent.empty()
+                        ? SkString("Chromium")
+                        : SkString(user_agent.c_str(), user_agent.size()));
   SkTime::DateTime now = TimeToSkTime(base::Time::Now());
   pdf_doc->setMetadata(info, &now, &now);
   if (!pdf_doc->close())
diff --git a/printing/print_settings.cc b/printing/print_settings.cc
index b1c50c9..7f555f0d 100644
--- a/printing/print_settings.cc
+++ b/printing/print_settings.cc
@@ -5,12 +5,23 @@
 #include "printing/print_settings.h"
 
 #include "base/atomic_sequence_num.h"
+#include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "printing/print_job_constants.h"
 #include "printing/units.h"
 
 namespace printing {
 
+base::LazyInstance<std::string> g_user_agent;
+
+void SetAgent(const std::string& user_agent) {
+  g_user_agent.Get() = user_agent;
+}
+
+const std::string& GetAgent() {
+  return g_user_agent.Get();
+}
+
 #if defined(USE_CUPS)
 void GetColorModelForMode(
     int color_mode, std::string* color_setting_name, std::string* color_value) {
diff --git a/printing/print_settings.h b/printing/print_settings.h
index 1f35e90b..08c7d56 100644
--- a/printing/print_settings.h
+++ b/printing/print_settings.h
@@ -26,6 +26,11 @@
                                           std::string* color_value);
 #endif
 
+// Inform the printing system that it may embed this user-agent string
+// in its output's metadata.
+PRINTING_EXPORT void SetAgent(const std::string& user_agent);
+PRINTING_EXPORT const std::string& GetAgent();
+
 // OS-independent print settings.
 class PRINTING_EXPORT PrintSettings {
  public:
diff --git a/remoting/resources/remoting_strings_de.xtb b/remoting/resources/remoting_strings_de.xtb
index 5f0addf8..71818ba 100644
--- a/remoting/resources/remoting_strings_de.xtb
+++ b/remoting/resources/remoting_strings_de.xtb
@@ -207,7 +207,7 @@
 <translation id="6284412385303060032">Der Host, der auf dem Anmeldebildschirm für die Konsole ausgeführt wird, wurde heruntergefahren, um den Vorhangmodus zu unterstützen, indem zu einem Host in einer nutzerspezfischen Sitzung gewechselt wurde.</translation>
 <translation id="629730747756840877">Konto</translation>
 <translation id="6304318647555713317">Client</translation>
-<translation id="6324708100353784493">Sie haben den Google Cardboard-Integrationsmodus aktiviert. Um diesen Modus zu verwenden, legen Sie Ihr Gerät in ein mit Google Cardboard kompatibles Lesegerät ein.</translation>
+<translation id="6324708100353784493">Sie haben den Google Cardboard-Integrationsmodus aktiviert. Um diesen Modus zu verwenden, legen Sie Ihr Gerät in eine mit Google Cardboard kompatible VR-Brille ein.</translation>
 <translation id="6381670701864002291">Sonstige</translation>
 <translation id="6398765197997659313">Vollbildmodus beenden</translation>
 <translation id="6441316101718669559">Die Desktop-Integration wird auf dieser Plattform nicht unterstützt. Sie können die App weiterhin verwenden, allerdings ist die Benutzerfreundlichkeit beeinträchtigt.</translation>
diff --git a/remoting/resources/remoting_strings_fa.xtb b/remoting/resources/remoting_strings_fa.xtb
index 2bd147f..aaa459b9 100644
--- a/remoting/resources/remoting_strings_fa.xtb
+++ b/remoting/resources/remoting_strings_fa.xtb
@@ -68,7 +68,7 @@
 <translation id="2370754117186920852"><ph name="OPTIONAL_OFFLINE_REASON" />  آخرین حضور آنلاین <ph name="RELATIVE_TIMESTAMP" />.</translation>
 <translation id="2498359688066513246">راهنمایی و بازخورد</translation>
 <translation id="2499160551253595098">‏با اجازه به ما جهت جمع‌آوری آمار مربوط به استفاده و گزارش‌های خرابی، کمک کنید تا کنترل دسک تاپ از راه دور Chrome را ارتقا دهیم.</translation>
-<translation id="2512228156274966424">‏توجه: برای اطمینان از اینکه همه میانبرهای صفحه کلید در دسترس هستند، می‌توانید کنترل دسک‌تاپ از راه دور Chrome را روی «بازکردن به عنوان پنجره» پیکربندی کنید.</translation>
+<translation id="2512228156274966424">‏توجه: برای اطمینان از اینکه همه میان‌برهای صفحه‌کلید در دسترس هستند، می‌توانید کنترل دسک‌تاپ از راه دور Chrome را روی «بازکردن به عنوان پنجره» پیکربندی کنید.</translation>
 <translation id="2540992418118313681">می‌خواهید این رایانه را برای کاربر دیگر جهت مشاهده و کنترل به اشتراک بگذارید؟</translation>
 <translation id="2599300881200251572">‏این سرویس اتصالات ورودی از کلاینت‌های کنترل دسک‌تاپ از راه دور Chrome را فعال می‌کند.</translation>
 <translation id="2647232381348739934">‏سرویس کار با Chrome</translation>
@@ -141,7 +141,7 @@
 <translation id="4472575034687746823">شروع به کار</translation>
 <translation id="4481276415609939789">‏رایانه‌ای ثبت نشده است. برای فعال کردن اتصالات راه دور به رایانه، کار با Chrome را فعال کنید و روی «<ph name="BUTTON_NAME" />» کلیک کنید.</translation>
 <translation id="4513946894732546136">بازخورد</translation>
-<translation id="4517233780764084060">‏توجه: برای اطمینان از اینکه همه میان‌برهای صفحه کلید در دسترس هستند، می‌توانید کار با Chrome را روی «بازکردن بعنوان پنجره» پیکربندی کنید.</translation>
+<translation id="4517233780764084060">‏توجه: برای اطمینان از اینکه همه میان‌برهای صفحه‌کلید در دسترس هستند، می‌توانید کار با Chrome را روی «بازکردن بعنوان پنجره» پیکربندی کنید.</translation>
 <translation id="4563926062592110512">کلاینت قطع شد: <ph name="CLIENT_USERNAME" />.</translation>
 <translation id="4572065712096155137">دسترسی</translation>
 <translation id="4573676252416618192">‏برنامه میزبان کنترل
diff --git a/remoting/resources/remoting_strings_hu.xtb b/remoting/resources/remoting_strings_hu.xtb
index c50a2ec..a971ba2 100644
--- a/remoting/resources/remoting_strings_hu.xtb
+++ b/remoting/resources/remoting_strings_hu.xtb
@@ -181,7 +181,7 @@
 <translation id="5510035215749041527">Leválasztás most</translation>
 <translation id="5537725057119320332">Küldés</translation>
 <translation id="5593560073513909978">A szolgáltatás átmenetileg nem érhető el. Kérjük, próbálkozzon újra később.</translation>
-<translation id="5601503069213153581">PIN kód</translation>
+<translation id="5601503069213153581">PIN-kód</translation>
 <translation id="5619148062500147964">Ehhez a számítógéphez</translation>
 <translation id="5625493749705183369">Más számítógépek elérése vagy annak engedélyezése, hogy más biztonságosan elérje a számítógépet az interneten keresztül.</translation>
 <translation id="5702987232842159181">Csatlakoztatva:</translation>
@@ -201,7 +201,7 @@
 <translation id="6173536234069435147">Nem tudom megnyitni a Google Drive-fájlokat.</translation>
 <translation id="6178645564515549384">Natív üzenetváltási szerver távoli segítségnyújtáshoz</translation>
 <translation id="6193698048504518729">Csatlakozás a következőhöz: <ph name="HOSTNAME" /></translation>
-<translation id="6198252989419008588">PIN kód megváltoztatása</translation>
+<translation id="6198252989419008588">PIN-kód megváltoztatása</translation>
 <translation id="6204583485351780592"><ph name="HOSTNAME" /> (elavult)</translation>
 <translation id="6221358653751391898">Nincs bejelentkezve a Chrome-ba. Jelentkezzen be, és próbálkozzon újra.</translation>
 <translation id="6284412385303060032">A konzol logikai képernyőjén futó gazdagép leállt, hogy támogassa a rejtett üzemmódot úgy, hogy felhasználóspecifikus munkamenetben futó gazdagépre váltott.</translation>
@@ -211,7 +211,7 @@
 <translation id="6381670701864002291">Valami más.</translation>
 <translation id="6398765197997659313">Kilépés a teljes képernyős módból</translation>
 <translation id="6441316101718669559">Ez az operációs rendszer nem támogatja az asztali integrációt. Az alkalmazást használhatja, de a felhasználói élmény nem lesz teljes.</translation>
-<translation id="652218476070540101">A számítógéphez tartozó PIN kód frissítése folyamatban...</translation>
+<translation id="652218476070540101">A számítógéphez tartozó PIN-kód frissítése folyamatban...</translation>
 <translation id="6527303717912515753">Megosztás</translation>
 <translation id="6541219117979389420">Az alkalmazásnaplók tartalmazhatnak privát adatokat, többek között az Ön személyazonosságát (e-mail címét), valamint a Google Drive-on lévő fájlok és mappák neveit és tulajdonságait.</translation>
 <translation id="6542902059648396432">Hiba bejelentése…</translation>
@@ -219,7 +219,7 @@
 <translation id="6570205395680337606">Alkalmazás visszaállítása. A nem mentett munkája el fog veszni.</translation>
 <translation id="6612717000975622067">Ctrl-Alt-Del küldése</translation>
 <translation id="6640610550128933069">utoljára ekkor volt online: <ph name="DATE" /></translation>
-<translation id="6668065415969892472">A PIN kód frissült.</translation>
+<translation id="6668065415969892472">A PIN-kód frissült.</translation>
 <translation id="6681800064886881394">Copyright 2013 – Google Inc. Minden jog fenntartva.</translation>
 <translation id="6746493157771801606">Előzmények törlése</translation>
 <translation id="6748108480210050150">Innen:</translation>
diff --git a/remoting/resources/remoting_strings_iw.xtb b/remoting/resources/remoting_strings_iw.xtb
index 0d79dc7..fed1036 100644
--- a/remoting/resources/remoting_strings_iw.xtb
+++ b/remoting/resources/remoting_strings_iw.xtb
@@ -207,7 +207,7 @@
 <translation id="6284412385303060032">המארח הפועל במסך הכניסה למסוף כבה כדי לתמוך במצב הסתרה על ידי מעבר אל מארח הרץ בפעילות באתר שהיא ספציפית למשתמש.</translation>
 <translation id="629730747756840877">חשבון</translation>
 <translation id="6304318647555713317">לקוח</translation>
-<translation id="6324708100353784493">‏הפעלת מצב האינטגרציה של Google Cardboard. כדי להשתמש במצב זה, הכנס את המכשיר לתוך מציג התואם ל-Google Cardboard.</translation>
+<translation id="6324708100353784493">‏הפעלת את מצב האינטגרציה של Google Cardboard. כדי להשתמש במצב זה, הכנס את המכשיר למציג התואם ל-Google Cardboard.</translation>
 <translation id="6381670701864002291">משהו אחר.</translation>
 <translation id="6398765197997659313">צא ממסך מלא</translation>
 <translation id="6441316101718669559">שילוב של שולחן עבודה אינו נתמך בפלטפורמה זו. תוכל עדיין להשתמש ביישום, אבל תהיה לכך השפעה שלילית על חוויית המשתמש.</translation>
diff --git a/remoting/resources/remoting_strings_ja.xtb b/remoting/resources/remoting_strings_ja.xtb
index d22855e..2aac6c2 100644
--- a/remoting/resources/remoting_strings_ja.xtb
+++ b/remoting/resources/remoting_strings_ja.xtb
@@ -207,7 +207,7 @@
 <translation id="6284412385303060032">コンソールのログイン画面で実行されるホストは、カーテンモードをサポートするために終了されました(ユーザー固有のセッションで実行されるホストに切り替えられました)。</translation>
 <translation id="629730747756840877">アカウント</translation>
 <translation id="6304318647555713317">クライアント</translation>
-<translation id="6324708100353784493">Google Cardboard 統合モードを有効にしました。このモードを使用するには、端末に Google Cardboard 対応ビューアを装着してください。</translation>
+<translation id="6324708100353784493">Google Cardboard 統合モードを有効にしました。このモードを使用するには、端末を Google Cardboard 対応ビューアに装着してください。</translation>
 <translation id="6381670701864002291">その他の問題。</translation>
 <translation id="6398765197997659313">全画面表示を終了</translation>
 <translation id="6441316101718669559">このプラットフォームでデスクトップの統合はサポートされていません。アプリケーションは引き続き使用できますが、ユーザー エクスペリエンスは低下します。</translation>
diff --git a/remoting/resources/remoting_strings_ko.xtb b/remoting/resources/remoting_strings_ko.xtb
index b9278dc5..dfc1d538 100644
--- a/remoting/resources/remoting_strings_ko.xtb
+++ b/remoting/resources/remoting_strings_ko.xtb
@@ -207,7 +207,7 @@
 <translation id="6284412385303060032">콘솔 로직 화면에서 실행 중인 호스트가 사용자별 세션에서 실행 중인 호스트로 전환하여 커튼 모드를 지원하기 위해 종료되었습니다.</translation>
 <translation id="629730747756840877">계정</translation>
 <translation id="6304318647555713317">클라이언트</translation>
-<translation id="6324708100353784493">Google Cardboard 통합 모드를 사용하도록 설정했습니다. 이 모드를 사용하려면 Google Cardboard와 호환되는 뷰어에 기기를 삽입하세요.</translation>
+<translation id="6324708100353784493">Google Cardboard 통합 모드를 사용하도록 설정했습니다. 이 모드를 사용하려면 Google Cardboard 호환 뷰어에 기기를 삽입하세요.</translation>
 <translation id="6381670701864002291">기타 문제</translation>
 <translation id="6398765197997659313">전체화면 닫기</translation>
 <translation id="6441316101718669559">데스크톱 통합이 이 플랫폼에서 지원되지 않습니다. 애플리케이션을 사용할 수는 있지만, 사용자 환경이 저하될 수 있습니다.</translation>
diff --git a/remoting/resources/remoting_strings_pl.xtb b/remoting/resources/remoting_strings_pl.xtb
index 9fa127b..3f32252 100644
--- a/remoting/resources/remoting_strings_pl.xtb
+++ b/remoting/resources/remoting_strings_pl.xtb
@@ -207,7 +207,7 @@
 <translation id="6284412385303060032">Host uruchomiony na ekranie logowania konsoli został zamknięty, by umożliwić włączenie trybu kurtyny, przełączając się na hosta uruchomionego w sesji danego użytkownika.</translation>
 <translation id="629730747756840877">Konto</translation>
 <translation id="6304318647555713317">Klient</translation>
-<translation id="6324708100353784493">Włączono tryb integracji Google Cardboard. Aby z niego skorzystać, umieść swoje urządzenie w goglach zgodnych z Google Cardboard.</translation>
+<translation id="6324708100353784493">Włączyłeś tryb integracji Google Cardboard. Aby z niego skorzystać, umieść swoje urządzenie w goglach zgodnych z Google Cardboard.</translation>
 <translation id="6381670701864002291">Inny problem.</translation>
 <translation id="6398765197997659313">Zamknij pełny ekran</translation>
 <translation id="6441316101718669559">Integracja pulpitu jest niedostępna na tej platformie. Wciąż możesz używać aplikacji, jednak praca będzie mniej wygodna.</translation>
diff --git a/remoting/resources/remoting_strings_sl.xtb b/remoting/resources/remoting_strings_sl.xtb
index 2fb8e310..333be177 100644
--- a/remoting/resources/remoting_strings_sl.xtb
+++ b/remoting/resources/remoting_strings_sl.xtb
@@ -207,7 +207,7 @@
 <translation id="6284412385303060032">Gostitelj, ki se je izvajal na zaslonu za prijavo v konzolo, se je zaustavil zaradi podpore načinu zavese, tako da je preklopil na gostitelja, ki se izvaja v seji uporabnika.</translation>
 <translation id="629730747756840877">Račun</translation>
 <translation id="6304318647555713317">Odjemalec</translation>
-<translation id="6324708100353784493">Omogočili ste način integracije z Googlom Cardboard. Za uporabo tega načina vstavite napravo v pregledovalnik, združljiv z Google Cardboardom.</translation>
+<translation id="6324708100353784493">Omogočili ste način integracije z Googlom Cardboard. Za uporabo tega načina vstavite napravo v pregledovalnik, združljiv z Googlom Cardboard.</translation>
 <translation id="6381670701864002291">Nekaj drugega.</translation>
 <translation id="6398765197997659313">Izhod iz celozaslonskega načina</translation>
 <translation id="6441316101718669559">Integracija namizja v tem okolju ni podprta. Aplikacijo lahko še vedno uporabljate, vendar bo uporabniška izkušnja okrnjena.</translation>
diff --git a/remoting/resources/remoting_strings_sw.xtb b/remoting/resources/remoting_strings_sw.xtb
index 9ce005e..a41e2e9 100644
--- a/remoting/resources/remoting_strings_sw.xtb
+++ b/remoting/resources/remoting_strings_sw.xtb
@@ -207,7 +207,7 @@
 <translation id="6284412385303060032">Seva pangishi inayotumika kwenye skrini ya dashibodi imezima ili kutumia hali ya pazia kwa kubadilisha hadi seva pangishi inayotumika katika kipindi mahususi cha mtumiaji.</translation>
 <translation id="629730747756840877">Akaunti</translation>
 <translation id="6304318647555713317">Kiteja</translation>
-<translation id="6324708100353784493">Umewasha kipengee cha hali ya kujumuisha ya Google Cardboard. Ili utumie hali hii, weka kifaa chako katika mwonekano unaotumika kwenye Google Cardboard.</translation>
+<translation id="6324708100353784493">Umewasha kipengee cha hali ya kujumuisha Google Cardboard. Ili utumie hali hii, weka kifaa chako katika mwonekano unaotumika kwenye Google Cardboard.</translation>
 <translation id="6381670701864002291">Kitu kingine.</translation>
 <translation id="6398765197997659313">Ondoka kwenye Skrini nzima</translation>
 <translation id="6441316101718669559">Ujumuishaji wa eneo-kazi hautumiki kwenye mfumo huu. Bado unaweza kutumia programu, lakini hali ya mtumiaji itaharibiwa.</translation>
diff --git a/remoting/resources/remoting_strings_th.xtb b/remoting/resources/remoting_strings_th.xtb
index e529616..672771a0 100644
--- a/remoting/resources/remoting_strings_th.xtb
+++ b/remoting/resources/remoting_strings_th.xtb
@@ -207,7 +207,7 @@
 <translation id="6284412385303060032">โฮสต์ที่ทำงานที่หน้าจอตรรกะของคอนโซลได้ปิดตัวลงเพื่อสนับสนุนโหมด Curtain โดยการเปลี่ยนไปเป็นโฮสต์ที่ทำงานในเซสชันเฉพาะผู้ใช้</translation>
 <translation id="629730747756840877">บัญชี</translation>
 <translation id="6304318647555713317">ไคลเอ็นต์</translation>
-<translation id="6324708100353784493">คุณได้เปิดใช้โหมดการผนวกรวม Google Cardboard หากต้องการใช้โหมดนี้ ให้เสียบอุปกรณ์ของคุณเข้ากับตัวดูภาพที่ใช้งานได้กับ Google Cardboard</translation>
+<translation id="6324708100353784493">คุณได้เปิดใช้โหมดการผนวกรวม Google Cardboard หากต้องการใช้โหมดนี้ ให้ใส่อุปกรณ์ของคุณในอุปกรณ์ดูภาพที่ใช้งานได้กับ Google Cardboard</translation>
 <translation id="6381670701864002291">มีปัญหาอื่น</translation>
 <translation id="6398765197997659313">ออกจากการแสดงแบบเต็มหน้าจอ</translation>
 <translation id="6441316101718669559">การรวมระบบเดสก์ท็อปไม่ได้รับการสนับสนุนบนแพลตฟอร์มนี้ คุณยังคงสามารถใช้แอปพลิเคชันนี้ได้ แต่ประสบการณ์ของผู้ใช้จะมีคุณภาพลดลง</translation>
diff --git a/skia/ext/platform_canvas.cc b/skia/ext/platform_canvas.cc
index 5e5aeb2..cf362b3 100644
--- a/skia/ext/platform_canvas.cc
+++ b/skia/ext/platform_canvas.cc
@@ -20,6 +20,23 @@
   return bitmap;
 }
 
+bool GetWritablePixels(SkCanvas* canvas, SkPixmap* result) {
+  if (!canvas || !result) {
+    return false;
+  }
+
+  SkImageInfo info;
+  size_t row_bytes;
+  void* pixels = canvas->accessTopLayerPixels(&info, &row_bytes);
+  if (!pixels) {
+    result->reset();
+    return false;
+  }
+
+  result->reset(info, pixels, row_bytes);
+  return true;
+}
+
 bool SupportsPlatformPaint(const SkCanvas* canvas) {
   PlatformDevice* platform_device = GetPlatformDevice(GetTopDevice(*canvas));
   return platform_device && platform_device->SupportsPlatformPaint();
diff --git a/skia/ext/platform_canvas.h b/skia/ext/platform_canvas.h
index 4499041..c46d6c4c 100644
--- a/skia/ext/platform_canvas.h
+++ b/skia/ext/platform_canvas.h
@@ -13,6 +13,7 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPixelRef.h"
+#include "third_party/skia/include/core/SkPixmap.h"
 
 namespace skia {
 
@@ -123,6 +124,15 @@
 // of the pixels.
 SK_API SkBitmap ReadPixels(SkCanvas* canvas);
 
+// Gives the pixmap passed in *writable* access to the pixels backing this
+// canvas. All writes to the pixmap should be visible if the canvas is
+// raster-backed.
+//
+// Returns false on failure: if either argument is nullptr, or if the
+// pixels can not be retrieved from the canvas. In the latter case resets
+// the pixmap to empty.
+SK_API bool GetWritablePixels(SkCanvas* canvas, SkPixmap* pixmap);
+
 // Returns true if native platform routines can be used to draw on the
 // given canvas. If this function returns false, BeginPlatformPaint will
 // return NULL PlatformSurface.
diff --git a/skia/ext/skia_utils_mac.h b/skia/ext/skia_utils_mac.h
index b60f9e8..e99913f7 100644
--- a/skia/ext/skia_utils_mac.h
+++ b/skia/ext/skia_utils_mac.h
@@ -10,6 +10,7 @@
 
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "third_party/skia/include/core/SkPixmap.h"
 
 struct SkIRect;
 struct SkPoint;
@@ -129,12 +130,13 @@
   bool userClipRectSpecified_;
 
   CGContextRef cgContext_;
-  SkBitmap bitmap_;
+  // offscreen_ is only valid if useDeviceBits_ is false
+  SkBitmap offscreen_;
   SkIPoint bitmapOffset_;
   SkScalar bitmapScaleFactor_;
 
-  // True if we are drawing to |canvas_|'s SkBaseDevice's bits directly through
-  // |bitmap_|. Otherwise, the bits in |bitmap_| are our allocation and need to
+  // True if we are drawing to |canvas_|'s backing store directly.
+  // Otherwise, the bits in |bitmap_| are our allocation and need to
   // be copied over to |canvas_|.
   bool useDeviceBits_;
 
diff --git a/skia/ext/skia_utils_mac.mm b/skia/ext/skia_utils_mac.mm
index 9e552eb..fe05464c 100644
--- a/skia/ext/skia_utils_mac.mm
+++ b/skia/ext/skia_utils_mac.mm
@@ -11,6 +11,7 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/memory/scoped_ptr.h"
 #include "skia/ext/bitmap_platform_device_mac.h"
+#include "skia/ext/platform_canvas.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "third_party/skia/include/utils/mac/SkCGUtils.h"
 
@@ -297,15 +298,15 @@
   // If the user specified a clip region, assume that it was tight and that the
   // dirty rect is approximately the whole bitmap.
   if (userClipRectSpecified_)
-    return SkIRect::MakeWH(bitmap_.width(), bitmap_.height());
+    return SkIRect::MakeWH(offscreen_.width(), offscreen_.height());
 
   // Find the bits that were drawn to.
-  SkAutoLockPixels lockedPixels(bitmap_);
+  SkAutoLockPixels lockedPixels(offscreen_);
   const uint32_t* pixelBase
-      = reinterpret_cast<uint32_t*>(bitmap_.getPixels());
-  int rowPixels = bitmap_.rowBytesAsPixels();
-  int width = bitmap_.width();
-  int height = bitmap_.height();
+      = reinterpret_cast<uint32_t*>(offscreen_.getPixels());
+  int rowPixels = offscreen_.rowBytesAsPixels();
+  int width = offscreen_.width();
+  int height = offscreen_.height();
   SkIRect bounds;
   bounds.fTop = 0;
   int x;
@@ -367,13 +368,11 @@
 void SkiaBitLocker::releaseIfNeeded() {
   if (!cgContext_)
     return;
-  if (useDeviceBits_) {
-    bitmap_.unlockPixels();
-  } else if (!bitmapIsDummy_) {
+  if (!useDeviceBits_ && !bitmapIsDummy_) {
     // Find the bits that were drawn to.
     SkIRect bounds = computeDirtyRect();
     SkBitmap subset;
-    if (!bitmap_.extractSubset(&subset, bounds)) {
+    if (!offscreen_.extractSubset(&subset, bounds)) {
         return;
     }
     subset.setImmutable();  // Prevents a defensive copy inside Skia.
@@ -414,41 +413,49 @@
   // Now make clip_bounds be relative to the current layer/device
   clip_bounds.offset(-device->getOrigin());
 
-  const SkBitmap& deviceBits = device->accessBitmap(true);
+  SkPixmap devicePixels;
+  skia::GetWritablePixels(canvas_, &devicePixels);
 
   // Only draw directly if we have pixels, and we're only rect-clipped.
   // If not, we allocate an offscreen and draw into that, relying on the
   // compositing step to apply skia's clip.
-  useDeviceBits_ = deviceBits.getPixels() &&
+  useDeviceBits_ = devicePixels.addr() &&
                    canvas_->isClipRect() &&
                    !bitmapIsDummy_;
+  base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace(
+      CGColorSpaceCreateDeviceRGB());
+
+  int displayHeight;
   if (useDeviceBits_) {
-    bool result = deviceBits.extractSubset(&bitmap_, clip_bounds);
+    SkPixmap subset;
+    bool result = devicePixels.extractSubset(&subset, clip_bounds);
     DCHECK(result);
     if (!result)
       return 0;
-    bitmap_.lockPixels();
+    displayHeight = subset.height();
+    cgContext_ = CGBitmapContextCreate(subset.writable_addr(), subset.width(),
+      subset.height(), 8, subset.rowBytes(), colorSpace, 
+      kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
   } else {
-    bool result = bitmap_.tryAllocN32Pixels(
+    bool result = offscreen_.tryAllocN32Pixels(
         SkScalarCeilToInt(bitmapScaleFactor_ * clip_bounds.width()),
         SkScalarCeilToInt(bitmapScaleFactor_ * clip_bounds.height()));
     DCHECK(result);
     if (!result)
       return 0;
-    bitmap_.eraseColor(0);
+    offscreen_.eraseColor(0);
+    displayHeight = offscreen_.height();
+    cgContext_ = CGBitmapContextCreate(offscreen_.getPixels(),
+      offscreen_.width(), offscreen_.height(), 8, offscreen_.rowBytes(),
+      colorSpace, kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
   }
-  base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace(
-      CGColorSpaceCreateDeviceRGB());
-  cgContext_ = CGBitmapContextCreate(bitmap_.getPixels(), bitmap_.width(),
-    bitmap_.height(), 8, bitmap_.rowBytes(), colorSpace, 
-    kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
   DCHECK(cgContext_);
 
   SkMatrix matrix = canvas_->getTotalMatrix();
   matrix.postTranslate(-SkIntToScalar(bitmapOffset_.x()),
                        -SkIntToScalar(bitmapOffset_.y()));
   matrix.postScale(bitmapScaleFactor_, -bitmapScaleFactor_);
-  matrix.postTranslate(0, SkIntToScalar(bitmap_.height()));
+  matrix.postTranslate(0, SkIntToScalar(displayHeight));
 
   CGContextConcatCTM(cgContext_, SkMatrixToCGAffineTransform(matrix));
   
diff --git a/sql/connection.cc b/sql/connection.cc
index 79264916..3d584a6 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -190,6 +190,16 @@
   return rc;
 }
 
+// Convenience to get the sqlite3_file* and the size for the "main" database.
+int GetSqlite3FileAndSize(sqlite3* db,
+                          sqlite3_file** file, sqlite3_int64* db_size) {
+  int rc = GetSqlite3File(db, file);
+  if (rc != SQLITE_OK)
+    return rc;
+
+  return (*file)->pMethods->xFileSize(*file, db_size);
+}
+
 // This should match UMA_HISTOGRAM_MEDIUM_TIMES().
 base::HistogramBase* GetMediumTimeHistogram(const std::string& name) {
   return base::Histogram::FactoryTimeGet(
@@ -515,12 +525,8 @@
     return;
 
   sqlite3_file* file = NULL;
-  int rc = GetSqlite3File(db_, &file);
-  if (rc != SQLITE_OK)
-    return;
-
   sqlite3_int64 file_size = 0;
-  rc = file->pMethods->xFileSize(file, &file_size);
+  int rc = GetSqlite3FileAndSize(db_, &file, &file_size);
   if (rc != SQLITE_OK)
     return;
 
@@ -1656,6 +1662,23 @@
     return false;
   }
 
+  // Set a reasonable chunk size for larger files.  This reduces churn from
+  // remapping memory on size changes.  It also reduces filesystem
+  // fragmentation.
+  // TODO(shess): It may make sense to have this be hinted by the client.
+  // Database sizes seem to be bimodal, some clients have consistently small
+  // databases (<20k) while other clients have a broad distribution of sizes
+  // (hundreds of kilobytes to many megabytes).
+  sqlite3_file* file = NULL;
+  sqlite3_int64 db_size = 0;
+  int rc = GetSqlite3FileAndSize(db_, &file, &db_size);
+  if (rc == SQLITE_OK && db_size > 16 * 1024) {
+    int chunk_size = 4 * 1024;
+    if (db_size > 128 * 1024)
+      chunk_size = 32 * 1024;
+    sqlite3_file_control(db_, NULL, SQLITE_FCNTL_CHUNK_SIZE, &chunk_size);
+  }
+
   // Enable memory-mapped access.  The explicit-disable case is because SQLite
   // can be built to default-enable mmap.  This value will be capped by
   // SQLITE_MAX_MMAP_SIZE, which could be different between 32-bit and 64-bit
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc
index 5fcacd5..36632c6 100644
--- a/storage/browser/quota/quota_database.cc
+++ b/storage/browser/quota/quota_database.cc
@@ -275,7 +275,7 @@
   statement.BindInt(1, static_cast<int>(type));
 
   if (!statement.Step())
-    return statement.Succeeded();
+    return false;
 
   *last_modified_time = base::Time::FromInternalValue(statement.ColumnInt64(0));
   return true;
@@ -346,6 +346,31 @@
   return true;
 }
 
+bool QuotaDatabase::GetOriginInfo(const GURL& origin,
+                                  StorageType type,
+                                  QuotaDatabase::OriginInfoTableEntry* entry) {
+  if (!LazyOpen(false))
+    return false;
+
+  const char* kSql =
+      "SELECT * FROM OriginInfoTable"
+      " WHERE origin = ? AND type = ?";
+  sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
+  statement.BindString(0, origin.spec());
+  statement.BindInt(1, static_cast<int>(type));
+
+  if (!statement.Step())
+    return false;
+
+  *entry = OriginInfoTableEntry(
+      GURL(statement.ColumnString(0)),
+      static_cast<StorageType>(statement.ColumnInt(1)), statement.ColumnInt(2),
+      base::Time::FromInternalValue(statement.ColumnInt64(3)),
+      base::Time::FromInternalValue(statement.ColumnInt64(4)));
+
+  return true;
+}
+
 bool QuotaDatabase::DeleteHostQuota(
     const std::string& host, StorageType type) {
   if (!LazyOpen(false))
diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h
index e95fba8..dae5581f 100644
--- a/storage/browser/quota/quota_database.h
+++ b/storage/browser/quota/quota_database.h
@@ -36,6 +36,20 @@
 // All the methods of this class must run on the DB thread.
 class STORAGE_EXPORT_PRIVATE QuotaDatabase {
  public:
+  struct STORAGE_EXPORT_PRIVATE OriginInfoTableEntry {
+    OriginInfoTableEntry();
+    OriginInfoTableEntry(const GURL& origin,
+                         StorageType type,
+                         int used_count,
+                         const base::Time& last_access_time,
+                         const base::Time& last_modified_time);
+    GURL origin;
+    StorageType type;
+    int used_count;
+    base::Time last_access_time;
+    base::Time last_modified_time;
+  };
+
   // Constants for {Get,Set}QuotaConfigValue keys.
   static const char kDesiredAvailableSpaceKey[];
   static const char kTemporaryQuotaOverrideKey[];
@@ -46,7 +60,10 @@
 
   void CloseConnection();
 
+  // Returns whether the record could be found.
   bool GetHostQuota(const std::string& host, StorageType type, int64* quota);
+
+  // Returns whether the operation succeeded.
   bool SetHostQuota(const std::string& host, StorageType type, int64 quota);
   bool DeleteHostQuota(const std::string& host, StorageType type);
 
@@ -58,9 +75,14 @@
                                  StorageType type,
                                  base::Time last_modified_time);
 
+  // Gets the time |origin| was last evicted. Returns whether the record could
+  // be found.
   bool GetOriginLastEvictionTime(const GURL& origin,
                                  StorageType type,
                                  base::Time* last_eviction_time);
+
+  // Sets the time the origin was last evicted. Returns whether the operation
+  // succeeded.
   bool SetOriginLastEvictionTime(const GURL& origin,
                                  StorageType type,
                                  base::Time last_eviction_time);
@@ -72,6 +94,12 @@
   bool RegisterInitialOriginInfo(
       const std::set<GURL>& origins, StorageType type);
 
+  // Gets the OriginInfoTableEntry for |origin|. Returns whether the record
+  // could be found.
+  bool GetOriginInfo(const GURL& origin,
+                     StorageType type,
+                     OriginInfoTableEntry* entry);
+
   bool DeleteOriginInfo(const GURL& origin, StorageType type);
 
   bool GetQuotaConfigValue(const char* key, int64* value);
@@ -87,7 +115,7 @@
                     GURL* origin);
 
   // Populates |origins| with the ones that have been modified since
-  // the |modified_since|.
+  // the |modified_since|. Returns whether the operation succeeded.
   bool GetOriginsModifiedSince(StorageType type,
                                std::set<GURL>* origins,
                                base::Time modified_since);
@@ -111,21 +139,6 @@
   };
   friend STORAGE_EXPORT_PRIVATE bool operator <(
       const QuotaTableEntry& lhs, const QuotaTableEntry& rhs);
-
-  struct STORAGE_EXPORT_PRIVATE OriginInfoTableEntry {
-    OriginInfoTableEntry();
-    OriginInfoTableEntry(
-        const GURL& origin,
-        StorageType type,
-        int used_count,
-        const base::Time& last_access_time,
-        const base::Time& last_modified_time);
-    GURL origin;
-    StorageType type;
-    int used_count;
-    base::Time last_access_time;
-    base::Time last_modified_time;
-  };
   friend STORAGE_EXPORT_PRIVATE bool operator <(
       const OriginInfoTableEntry& lhs, const OriginInfoTableEntry& rhs);
 
diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc
index 0052f2d..c0f7560 100644
--- a/storage/browser/quota/quota_manager.cc
+++ b/storage/browser/quota/quota_manager.cc
@@ -76,6 +76,10 @@
 
 const char QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram[] =
     "Quota.TimeBetweenRepeatedOriginEvictions";
+const char QuotaManager::kEvictedOriginAccessedCountHistogram[] =
+    "Quota.EvictedOriginAccessCount";
+const char QuotaManager::kEvictedOriginTimeSinceAccessHistogram[] =
+    "Quota.EvictedOriginTimeSinceAccess";
 
 // Heuristics: assuming average cloud server allows a few Gigs storage
 // on the server side and the storage needs to be shared for user data
@@ -159,6 +163,19 @@
                                 bool is_eviction,
                                 QuotaDatabase* database) {
   DCHECK(database);
+
+  base::Time now = base::Time::Now();
+
+  if (is_eviction) {
+    QuotaDatabase::OriginInfoTableEntry entry;
+    database->GetOriginInfo(origin, type, &entry);
+    UMA_HISTOGRAM_COUNTS(QuotaManager::kEvictedOriginAccessedCountHistogram,
+                         entry.used_count);
+    UMA_HISTOGRAM_LONG_TIMES(
+        QuotaManager::kEvictedOriginTimeSinceAccessHistogram,
+        now - entry.last_access_time);
+  }
+
   if (!database->DeleteOriginInfo(origin, type))
     return false;
 
@@ -168,10 +185,8 @@
     return database->DeleteOriginLastEvictionTime(origin, type);
 
   base::Time last_eviction_time;
-  if (!database->GetOriginLastEvictionTime(origin, type, &last_eviction_time))
-    return false;
+  database->GetOriginLastEvictionTime(origin, type, &last_eviction_time);
 
-  base::Time now = base::Time::Now();
   if (last_eviction_time != base::Time()) {
     UMA_HISTOGRAM_LONG_TIMES(
         QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram,
diff --git a/storage/browser/quota/quota_manager.h b/storage/browser/quota/quota_manager.h
index bacf80b..2f9f16f7 100644
--- a/storage/browser/quota/quota_manager.h
+++ b/storage/browser/quota/quota_manager.h
@@ -277,6 +277,8 @@
   static const int kEvictionIntervalInMilliSeconds;
 
   static const char kTimeBetweenRepeatedOriginEvictionsHistogram[];
+  static const char kEvictedOriginAccessedCountHistogram[];
+  static const char kEvictedOriginTimeSinceAccessHistogram[];
 
   // These are kept non-const so that test code can change the value.
   // TODO(kinuko): Make this a real const value and add a proper way to set
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 31238764..7fe981c4 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -1184,7 +1184,10 @@
       },
       {
         "isolate_name": "telemetry_perf_unittests",
-        "name": "telemetry_perf_unittests"
+        "name": "telemetry_perf_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        }
       }
     ],
     "scripts": [
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index 40aa61d..4d8c73587 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -1607,12 +1607,6 @@
       {
         "test": "window_manager_unittests"
       }
-    ],
-    "scripts": [
-      {
-        "name": "mojo_apptests",
-        "script": "mojo_apptests.py"
-      }
     ]
   },
   "Win8 GN": {
diff --git a/testing/scripts/mojo_apptests.py b/testing/scripts/mojo_apptests.py
index 2672ad2c..49b855da2 100755
--- a/testing/scripts/mojo_apptests.py
+++ b/testing/scripts/mojo_apptests.py
@@ -16,7 +16,7 @@
   build_dir = os.path.join(common.SRC_DIR, 'out', args.build_config_fs)
 
   with common.temporary_file() as tempfile_path:
-    rc = common.run_command([sys.executable, runner, build_dir, '--verbose',
+    rc = common.run_command([runner, build_dir, '--verbose',
                              '--write-full-results-to', tempfile_path])
     with open(tempfile_path) as f:
       results = json.load(f)
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index e52e8a0..b272bb19 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -71,7 +71,6 @@
 crbug.com/492664 imported/csswg-test/css-transitions-2/transitioncancel-001.html [ Failure ]
 crbug.com/418091 [ Mac10.6 ] fast/text/aat-morx.html [ Failure ]
 crbug.com/463358 [ Mac Linux ] svg/hixie/perf/005.xml [ Pass Failure ]
-crbug.com/463358 [ Mac Linux ] svg/hixie/perf/006.xml [ Pass Failure ]
 crbug.com/463358 [ Linux Mac ] svg/transforms/text-with-pattern-inside-transformed-html.xhtml [ Failure ]
 crbug.com/463358 [ Mac Linux Debug ] fast/backgrounds/transformed-body-html-background.html [ Failure ]
 crbug.com/463358 [ Mac Linux Debug ] css3/masking/clip-path-polygon-nonzero.html [ Failure ]
@@ -921,7 +920,7 @@
 crbug.com/425113 svg/clip-path/clip-path-multiple-children.svg [ Failure ]
 
 crbug.com/480769 http/tests/inspector/service-workers/service-workers-redundant.html [ Crash Pass Slow Failure ]
-crbug.com/528198 http/tests/inspector/service-workers/service-worker-agents.html [ Crash Pass Slow ]
+crbug.com/480769 http/tests/inspector/service-workers/service-worker-agents.html [ Crash Pass Timeout Slow ]
 
 crbug.com/472330 fast/borders/border-image-outset-split-inline-vertical-lr.html [ Failure ]
 crbug.com/472330 fast/writing-mode/box-shadow-vertical-lr.html [ Failure ]
@@ -1002,6 +1001,9 @@
 crbug.com/474798 virtual/syncpaint/fast/repaint/align-self-change-keeping-geometry-grid.html [ Skip ]
 crbug.com/474798 virtual/syncpaint/fast/repaint/justify-self-change-keeping-geometry.html [ Skip ]
 
+crbug.com/548695 fast/forms/datalist/update-range-with-datalist.html [ Failure ]
+
+crbug.com/548705 fast/css/first-line-hover-001.html [ Failure ]
 
 # Temporarily disabled after chromium change
 crbug.com/492511 [ Mac ] fast/text/atsui-negative-spacing-features.html [ Failure ]
@@ -1291,7 +1293,6 @@
 crbug.com/521730 [ Win10 ] svg/text/text-selection-fonts-01-t.svg [ Failure ]
 crbug.com/521730 [ Win10 ] svg/text/text-selection-intro-05-t.svg [ Failure ]
 
-crbug.com/550430 fast/html/details-writing-mode.html [ Failure Pass ]
 crbug.com/550285 [ Mac10.6 ] virtual/syncpaint/compositing/repaint/newly-composited-on-scroll.html [ Failure ]
 crbug.com/550285 [ Mac10.6 ] virtual/syncpaint/fast/repaint/background-image-paint-invalidation-large-abspos-div.html [ Failure ]
 crbug.com/550285 [ Mac10.6 ] virtual/syncpaint/fast/repaint/repaint-during-scroll.html [ Failure ]
@@ -1339,6 +1340,8 @@
 crbug.com/538717 [ Win Mac Linux ] http/tests/permissions/chromium/test-request-multiple-worker.html [ Failure Pass Timeout ]
 crbug.com/538717 [ Win Mac Linux ] http/tests/permissions/chromium/test-request-multiple-sharedworker.html [ Failure Pass Timeout ]
 
+crbug.com/552033 inspector/console/console-format-es6.html [ NeedsManualRebaseline ]
+
 crbug.com/541601 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-defaults.xhtml [ Failure ]
 
 crbug.com/543369 [ Linux ] fast/forms/select/popup-menu-appearance-tall.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-amplitude-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-amplitude-composition.html
index 97c13c6..43cb9f4 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-amplitude-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-amplitude-composition.html
@@ -46,8 +46,6 @@
 assertAttributeInterpolation({
   property: 'amplitude',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-azimuth-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-azimuth-composition.html
index 227636b5..4a087f3 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-azimuth-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-azimuth-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'azimuth',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-bias-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-bias-composition.html
index e1d499fc..2ac454ba 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-bias-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-bias-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'bias',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-diffuseConstant-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-diffuseConstant-composition.html
index 8e108ac3..9954a91 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-diffuseConstant-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-diffuseConstant-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'diffuseConstant',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-divisor-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-divisor-composition.html
index b7e00f81..fdc687f5 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-divisor-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-divisor-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'divisor',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-elevation-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-elevation-composition.html
index 0ab832c..1b638da 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-elevation-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-elevation-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'elevation',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-exponent-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-exponent-composition.html
index 267fe931..9db687c 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-exponent-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-exponent-composition.html
@@ -46,8 +46,6 @@
 assertAttributeInterpolation({
   property: 'exponent',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-intercept-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-intercept-composition.html
index ef9799a..22c805b2 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-intercept-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-intercept-composition.html
@@ -46,8 +46,6 @@
 assertAttributeInterpolation({
   property: 'intercept',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-k1-k2-k3-k4-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-k1-k2-k3-k4-composition.html
index 5491945..0ad666cc 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-k1-k2-k3-k4-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-k1-k2-k3-k4-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'k1',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
@@ -92,8 +90,6 @@
 assertAttributeInterpolation({
   property: 'k2',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
@@ -140,8 +136,6 @@
 assertAttributeInterpolation({
   property: 'k3',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
@@ -188,8 +182,6 @@
 assertAttributeInterpolation({
   property: 'k4',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-limitingConeAngle-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-limitingConeAngle-composition.html
index a13ebe7..a56ddc9 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-limitingConeAngle-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-limitingConeAngle-composition.html
@@ -48,8 +48,6 @@
 assertAttributeInterpolation({
   property: 'limitingConeAngle',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-mode-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-mode-composition.html
new file mode 100644
index 0000000..df6771b6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-mode-composition.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<body>
+<template id="target-template">
+<svg width="0" height="0">
+<feBlend class="target" />
+</svg>
+</template>
+<script src="../svg-attribute-interpolation/resources/interpolation-test.js"></script>
+<script>
+'use strict';
+assertAttributeInterpolation({
+  property: 'mode',
+  underlying: 'multiply'
+  from: 'screen',
+  fromComposite: 'add',
+  to: 'lighten',
+  toComposite: 'add',
+}, [
+  {at: -2.4, is: 'screen'},
+  {at: 0, is: 'screen'},
+  {at: 0.2, is: 'screen'},
+  {at: 0.6, is: 'lighten'},
+  {at: 1, is: 'lighten'},
+  {at: 3.4, is: 'lighten'}
+]);
+
+assertAttributeInterpolation({
+  property: 'mode',
+  underlying: 'multiply'
+  to: 'lighten',
+  toComposite: 'replace',
+}, [
+  {at: -2.4, is: 'multiply'},
+  {at: 0, is: 'multiply'},
+  {at: 0.2, is: 'multiply'},
+  {at: 0.6, is: 'lighten'},
+  {at: 1, is: 'lighten'},
+  {at: 3.4, is: 'lighten'}
+]);
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-offset-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-offset-composition.html
index ee99a38..d0d85e9 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-offset-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-offset-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'offset',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-orient-composition-expected.txt b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-orient-composition-expected.txt
index 39187b3..dd75bfd 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-orient-composition-expected.txt
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-orient-composition-expected.txt
@@ -1,37 +1,37 @@
 CONSOLE WARNING: SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead.
 This is a testharness.js-based test.
 PASS This test uses interpolation-test.js. 
-PASS SMIL: Interpolate attribute <orient> from add [130] to add [200grad] at (0) is [180] 
-PASS SMIL: Interpolate attribute <orient> from add [130] to add [200grad] at (0.2) is [190] 
-PASS SMIL: Interpolate attribute <orient> from add [130] to add [200grad] at (0.6) is [210] 
-PASS SMIL: Interpolate attribute <orient> from add [130] to add [200grad] at (1) is [230] 
-PASS Web Animations: Interpolate attribute <orient> from add [130] to add [200grad] at (-3) is [30] 
-PASS Web Animations: Interpolate attribute <orient> from add [130] to add [200grad] at (0) is [180] 
-PASS Web Animations: Interpolate attribute <orient> from add [130] to add [200grad] at (0.2) is [190] 
-PASS Web Animations: Interpolate attribute <orient> from add [130] to add [200grad] at (0.6) is [210] 
-PASS Web Animations: Interpolate attribute <orient> from add [130] to add [200grad] at (1) is [230] 
-PASS Web Animations: Interpolate attribute <orient> from add [130] to add [200grad] at (1.4) is [250] 
-FAIL SMIL: Interpolate attribute <orient> from add [90deg] to add [auto] at (0) is [140] assert_equals: expected "140 " but got "90 "
-FAIL SMIL: Interpolate attribute <orient> from add [90deg] to add [auto] at (0.2) is [140] assert_equals: expected "140 " but got "90 "
-PASS SMIL: Interpolate attribute <orient> from add [90deg] to add [auto] at (0.6) is [auto] 
-PASS SMIL: Interpolate attribute <orient> from add [90deg] to add [auto] at (1) is [auto] 
-PASS Web Animations: Interpolate attribute <orient> from add [90deg] to add [auto] at (-0.4) is [140] 
-PASS Web Animations: Interpolate attribute <orient> from add [90deg] to add [auto] at (0) is [140] 
-PASS Web Animations: Interpolate attribute <orient> from add [90deg] to add [auto] at (0.2) is [140] 
-PASS Web Animations: Interpolate attribute <orient> from add [90deg] to add [auto] at (0.6) is [auto] 
-PASS Web Animations: Interpolate attribute <orient> from add [90deg] to add [auto] at (1) is [auto] 
-PASS Web Animations: Interpolate attribute <orient> from add [90deg] to add [auto] at (1.4) is [auto] 
-PASS Web Animations: Interpolate attribute <orient> from replace [120] to add [180] at (-0.4) is [88] 
-PASS Web Animations: Interpolate attribute <orient> from replace [120] to add [180] at (0) is [120] 
-PASS Web Animations: Interpolate attribute <orient> from replace [120] to add [180] at (0.2) is [136] 
-PASS Web Animations: Interpolate attribute <orient> from replace [120] to add [180] at (0.6) is [168] 
-PASS Web Animations: Interpolate attribute <orient> from replace [120] to add [180] at (1) is [200] 
-PASS Web Animations: Interpolate attribute <orient> from replace [120] to add [180] at (1.4) is [232] 
-PASS Web Animations: Interpolate attribute <orient> from add [] to replace [180] at (-0.4) is [-44] 
-PASS Web Animations: Interpolate attribute <orient> from add [] to replace [180] at (0) is [20] 
-PASS Web Animations: Interpolate attribute <orient> from add [] to replace [180] at (0.2) is [52] 
-PASS Web Animations: Interpolate attribute <orient> from add [] to replace [180] at (0.6) is [116] 
-PASS Web Animations: Interpolate attribute <orient> from add [] to replace [180] at (1) is [180] 
-PASS Web Animations: Interpolate attribute <orient> from add [] to replace [180] at (1.4) is [244] 
+PASS SMIL: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (0) is [180] 
+PASS SMIL: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (0.2) is [190] 
+PASS SMIL: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (0.6) is [210] 
+PASS SMIL: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (1) is [230] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (-3) is [30] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (0) is [180] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (0.2) is [190] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (0.6) is [210] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (1) is [230] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [130] to add [200grad] at (1.4) is [250] 
+FAIL SMIL: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (0) is [140] assert_equals: expected "140 " but got "90 "
+FAIL SMIL: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (0.2) is [140] assert_equals: expected "140 " but got "90 "
+PASS SMIL: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (0.6) is [auto] 
+PASS SMIL: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (1) is [auto] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (-0.4) is [140] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (0) is [140] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (0.2) is [140] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (0.6) is [auto] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (1) is [auto] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [50] from add [90deg] to add [auto] at (1.4) is [auto] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from replace [120] to add [180] at (-0.4) is [88] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from replace [120] to add [180] at (0) is [120] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from replace [120] to add [180] at (0.2) is [136] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from replace [120] to add [180] at (0.6) is [168] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from replace [120] to add [180] at (1) is [200] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from replace [120] to add [180] at (1.4) is [232] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from neutral to replace [180] at (-0.4) is [-44] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from neutral to replace [180] at (0) is [20] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from neutral to replace [180] at (0.2) is [52] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from neutral to replace [180] at (0.6) is [116] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from neutral to replace [180] at (1) is [180] 
+PASS Web Animations: Interpolate attribute <orient> with underlying [20] from neutral to replace [180] at (1.4) is [244] 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-orient-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-orient-composition.html
index ff0a8a2..9e45c6c 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-orient-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-orient-composition.html
@@ -59,8 +59,6 @@
 assertAttributeInterpolation({
   property: 'orient',
   underlying: '20',
-  from: '',
-  fromComposite: 'add',
   to: '180',
   toComposite: 'replace'
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-pathLength-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-pathLength-composition.html
index a13251c..944d7d1 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-pathLength-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-pathLength-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'pathLength',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-pointsAtX-pointsAtY-pointsAtZ-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-pointsAtX-pointsAtY-pointsAtZ-composition.html
index c8a9032..9376bae 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-pointsAtX-pointsAtY-pointsAtZ-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-pointsAtX-pointsAtY-pointsAtZ-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'pointsAtX',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
@@ -92,8 +90,6 @@
 assertAttributeInterpolation({
   property: 'pointsAtY',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
@@ -140,8 +136,6 @@
 assertAttributeInterpolation({
   property: 'pointsAtZ',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-scale-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-scale-composition.html
index 2a9db8ee..113e2d09 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-scale-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-scale-composition.html
@@ -48,8 +48,6 @@
 assertAttributeInterpolation({
   property: 'scale',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-seed-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-seed-composition.html
index db2aec8..b99da63 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-seed-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-seed-composition.html
@@ -48,8 +48,6 @@
 assertAttributeInterpolation({
   property: 'seed',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-slope-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-slope-composition.html
index a1d0ddd25..06cdd16 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-slope-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-slope-composition.html
@@ -46,8 +46,6 @@
 assertAttributeInterpolation({
   property: 'slope',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-specularConstant-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-specularConstant-composition.html
index 0c6c982..e7353465 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-specularConstant-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-specularConstant-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'specularConstant',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-specularExponent-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-specularExponent-composition.html
index 487f641f..170b1e47 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-specularExponent-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-specularExponent-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'specularExponent',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-surfaceScale-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-surfaceScale-composition.html
index 8ecc005..f3852de3 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-surfaceScale-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-surfaceScale-composition.html
@@ -44,8 +44,6 @@
 assertAttributeInterpolation({
   property: 'surfaceScale',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-z-composition.html b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-z-composition.html
index b9cf82d..23a2fe84 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-z-composition.html
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-composition/svg-z-composition.html
@@ -48,8 +48,6 @@
 assertAttributeInterpolation({
   property: 'z',
   underlying: '5',
-  from: '',
-  fromComposite: 'add',
   to: '10',
   toComposite: 'replace',
 }, [
diff --git a/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js b/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
index 233a360..5a44159 100644
--- a/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
+++ b/third_party/WebKit/LayoutTests/animations/svg-attribute-interpolation/resources/interpolation-test.js
@@ -3,11 +3,13 @@
  * found in the LICENSE file.
  *
  * Exported function:
- *  - assertAttributeInterpolation({property, from, to, [fromComposite], [toComposite], [underlying]}, [{at: fraction, is: value}])
+ *  - assertAttributeInterpolation({property, [from], [to], [fromComposite], [toComposite], [underlying]}, [{at: fraction, is: value}])
  *        Constructs a test case for each fraction that asserts the expected value
  *        equals the value produced by interpolation between from and to composited
  *        onto underlying by fromComposite and toComposite respectively using
  *        SMIL and Web Animations.
+ *        If from or to are missing then a neutral keyframe will be used and the
+ *        composite mode will be forced to be 'add'.
  *        SMIL will only be tested with equal fromComposite and toComposite values.
 */
 'use strict';
@@ -317,16 +319,26 @@
       case 'Web Animations':
         // Replace 'transform' with 'svgTransform', etc. This avoids collisions with CSS properties or the Web Animations API (offset).
         var prefixedProperty = 'svg' + params.property[0].toUpperCase() + params.property.slice(1);
-        target.animate([
-          {
+        var keyframes = [];
+        if ('from' in params) {
+          keyframes.push({
+            offset: 0,
             [prefixedProperty]: params.from,
             composite: params.fromComposite,
-          },
-          {
+          });
+        } else {
+          console.assert(params.fromComposite === 'add');
+        }
+        if ('to' in params) {
+          keyframes.push({
+            offset: 1,
             [prefixedProperty]: params.to,
             composite: params.toComposite,
-          },
-        ], {
+          });
+        } else {
+          console.assert(params.toComposite === 'add');
+        }
+        target.animate(keyframes, {
           fill: 'forwards',
           duration: 1,
           easing: createEasing(expectation.at),
@@ -356,13 +368,20 @@
     return target;
   }
 
+  function reprKeyframe(x) {
+    return (typeof x === 'string') ? "'" + x + "'" : null;
+  }
+
   function createTestTargets(interpolationTests, container, rebaselineContainer) {
     var targets = [];
     for (var interpolationTest of interpolationTests) {
       var params = interpolationTest.params;
-      params.fromComposite = params.fromComposite || 'replace';
-      params.toComposite = params.toComposite || 'replace';
-      var description = `Interpolate attribute <${params.property}> from ${params.fromComposite} [${params.from}] to ${params.toComposite} [${params.to}]`;
+      params.fromComposite = 'from' in params ? (params.fromComposite || 'replace') : 'add';
+      params.toComposite = 'to' in params ? (params.toComposite || 'replace') : 'add';
+      var underlyingText = params.underlying ? `with underlying [${params.underlying}] ` : '';
+      var fromText = 'from' in params ? `${params.fromComposite} [${params.from}]` : 'neutral';
+      var toText = 'to' in params ? `${params.toComposite} [${params.to}]` : 'neutral';
+      var description = `Interpolate attribute <${params.property}> ${underlyingText}from ${fromText} to ${toText}`;
 
     if (rebaselineTests) {
         var rebaseline = createElement('pre', rebaselineContainer);
@@ -370,9 +389,9 @@
 assertAttributeInterpolation({
   property: '${params.property}',
   underlying: '${params.underlying}',
-  from: '${params.from}',
+  from: ${reprKeyframe(params.from)},
   fromComposite: '${params.fromComposite}',
-  to: '${params.to}',
+  to: ${reprKeyframe(params.to)},
   toComposite: '${params.toComposite}',
 }, [\n`));
         var rebaselineExpectation;
diff --git a/third_party/WebKit/LayoutTests/bluetooth/getPrimaryService.html b/third_party/WebKit/LayoutTests/bluetooth/getPrimaryService.html
index d5e2d54..6bd46c6b 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/getPrimaryService.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/getPrimaryService.html
@@ -39,6 +39,28 @@
          gattServer.getPrimaryService(heart_rate.uuid), expected)]));
 }, 'Request for wrong service. Reject with NotFoundError.');
 
+promise_test(() => {
+  testRunner.setBluetoothMockDataSet('DelayedServicesDiscoveryAdapter');
+  return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]})
+    .then(device => device.connectGATT())
+    .then(gattServer => gattServer.getPrimaryService('heart_rate'))
+    .then(service => {
+      assert_equals(service.uuid, heart_rate.uuid);
+    });
+}, 'Request for service. Must return even when the services are not immediately discovered');
+
+promise_test(() => {
+  testRunner.setBluetoothMockDataSet('DelayedServicesDiscoveryAdapter');
+  return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]})
+    .then(device => device.connectGATT())
+    .then(gattServer => {
+      return assert_promise_rejects_with_message(
+        gattServer.getPrimaryService('battery_service'),
+        {name: 'NotFoundError', message: 'Service not found in device.'});
+    });
+}, 'Request for wrong service. Must reject with NotFoundError even when the services' +
+   ' are not immediately discovered');
+
 promise_test(function() {
   testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
   return requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]})
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container-expected.html b/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container-expected.html
deleted file mode 100644
index 10c401d..0000000
--- a/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container-expected.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<style>
-.block {
-    width: 50px;
-    height: 50px;
-    background-color: green;
-}
-
-</style>
-<p>crbug.com/322039: There should be a green <em>square</em> below.</p>
-<div>
-    <br>
-    <div id="first" class="block"></div>
-</div>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container.html b/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container.html
deleted file mode 100644
index 1780f6e..0000000
--- a/third_party/WebKit/LayoutTests/fast/block/float/add-inline-before-float-and-into-anonymous-block-container.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<style>
-.block {
-    width: 25px;
-    height: 50px;
-    background-color: green;
-}
-
-.float {
-    width: 25px;
-    height: 50px;
-    background-color: green;
-    float: left;
-}
-</style>
-<p>crbug.com/322039: There should be a green <em>square</em> below.</p>
-<div>
-    <div></div>
-    <br>
-    <div id="first" class="block"></div>
-    <div class="float"></div>
-</div>
-<script>
-        document.body.offsetTop;
-        document.getElementById("first").style.display = "inline-block";
-</script>
-
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/remove-div-after-float-and-before-anonymous-block-container.html b/third_party/WebKit/LayoutTests/fast/block/float/remove-div-after-float-and-before-anonymous-block-container.html
deleted file mode 100644
index c0bbc3c..0000000
--- a/third_party/WebKit/LayoutTests/fast/block/float/remove-div-after-float-and-before-anonymous-block-container.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<style>
-.block {
-    width: 50px;
-    height: 25px;
-    background-color: green;
-}
-
-.float {
-    width: 50px;
-    height: 25px;
-    background-color: green;
-    float: left;
-}
-</style>
-<p>crbug.com/322039: There should be a green <em>square</em> below. In the layout tree the float should be inside the anonymous block.</p>
-<div style="width: 150px;">
-    <div class="block"></div>
-    <div class="float"></div>
-    <div id="div"></div>
-    Text.
-</div>
-<script>
-        document.body.offsetTop;
-        var div = document.getElementById("div");
-        div.parentNode.removeChild(div);
-</script>
-
diff --git a/third_party/WebKit/LayoutTests/fast/css/webkit-column-span-legacy-expected.txt b/third_party/WebKit/LayoutTests/fast/css/webkit-column-span-legacy-expected.txt
new file mode 100644
index 0000000..86dfa39
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/webkit-column-span-legacy-expected.txt
@@ -0,0 +1,5 @@
+PASS getComputedStyle(div1).webkitColumnSpan is 'none'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/fast/css/webkit-column-span-legacy.html b/third_party/WebKit/LayoutTests/fast/css/webkit-column-span-legacy.html
new file mode 100644
index 0000000..884cf68a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/webkit-column-span-legacy.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML>
+<script src="../../resources/js-test.js"></script>
+
+<div id="-webkit-column-span" class="test" style="-webkit-column-span: 1;"></div>
+
+<script>
+var div1 = document.getElementById("-webkit-column-span");
+shouldBe("getComputedStyle(div1).webkitColumnSpan", "'none'");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties-expected.txt
index 6550e91..33e001e7 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties-expected.txt
@@ -3,25 +3,41 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-===Unscaled===
+===Initial Scale===
 
-PASS window.innerWidth is 800
-PASS window.innerHeight is 600
+PASS window.innerWidth is 1600
+PASS window.innerHeight is 1200
+PASS internals.visualViewportWidth() is 1600
+PASS internals.visualViewportHeight() is 1200
 
 ===Pinch Zoom in to 2X===
 
-PASS window.innerWidth is 400
-PASS window.innerHeight is 300
+PASS window.innerWidth is 1600
+PASS window.innerHeight is 1200
 PASS window.scrollX is 0
 PASS window.scrollY is 0
-PASS window.scrollX is 10
-PASS window.scrollY is 20
-PASS window.scrollX is 1600
-PASS window.scrollY is 1200
+PASS internals.visualViewportWidth() is 400
+PASS internals.visualViewportHeight() is 300
+===ScrollBy===
+PASS window.scrollX is 100
+PASS window.scrollY is 200
+PASS internals.visualViewportScrollX() is 100
+PASS internals.visualViewportScrollY() is 200
+PASS window.scrollX is 400
+PASS window.scrollY is 300
+PASS internals.visualViewportScrollX() is 400
+PASS internals.visualViewportScrollY() is 300
 PASS window.scrollX is 0
 PASS window.scrollY is 0
-PASS window.scrollX is 1600
-PASS window.scrollY is 1200
+===ScrollTo===
+PASS window.scrollX is 100
+PASS window.scrollY is 200
+PASS internals.visualViewportScrollX() is 100
+PASS internals.visualViewportScrollY() is 200
+PASS window.scrollX is 400
+PASS window.scrollY is 300
+PASS internals.visualViewportScrollX() is 400
+PASS internals.visualViewportScrollY() is 300
 PASS window.scrollX is 0
 PASS window.scrollY is 0
 
@@ -31,28 +47,30 @@
 PASS window.innerHeight is 1200
 PASS window.scrollX is 0
 PASS window.scrollY is 0
-PASS window.scrollX is 10
-PASS window.scrollY is 20
+PASS internals.visualViewportWidth() is 1600
+PASS internals.visualViewportHeight() is 1200
+===ScrollBy===
+PASS window.scrollX is 100
+PASS window.scrollY is 200
+PASS internals.visualViewportScrollX() is 100
+PASS internals.visualViewportScrollY() is 200
 PASS window.scrollX is 400
 PASS window.scrollY is 300
+PASS internals.visualViewportScrollX() is 400
+PASS internals.visualViewportScrollY() is 300
 PASS window.scrollX is 0
 PASS window.scrollY is 0
+===ScrollTo===
+PASS window.scrollX is 100
+PASS window.scrollY is 200
+PASS internals.visualViewportScrollX() is 100
+PASS internals.visualViewportScrollY() is 200
 PASS window.scrollX is 400
 PASS window.scrollY is 300
+PASS internals.visualViewportScrollX() is 400
+PASS internals.visualViewportScrollY() is 300
 PASS window.scrollX is 0
 PASS window.scrollY is 0
-
-===Test OnScroll===
-
-PASS window.innerWidth is 800
-PASS window.innerHeight is 600
-PASS window.scrollX is 0
-PASS window.scrollY is 0
-PASS OnScroll called for scroll #1
-PASS OnScroll called for scroll #2
-PASS OnScroll called for scroll #3
-PASS OnScroll called for scroll #4
-
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties.html b/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties.html
index 790c0bf..36b0d5a1 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties.html
@@ -1,9 +1,12 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<!DOCTYPE html>
 <script src="../../../resources/js-test.js"></script>
 <style>
   body {
     padding: 0px;
     margin: 0px;
+    /* Overflow hidden so that the size of the scrollbar is not added to
+    the innerHeight/Width properties. */
+    overflow: hidden;
   }
 
   .spacer {
@@ -18,45 +21,78 @@
 </style>
 <script language="JavaScript" type="text/javascript">
     if (window.testRunner && window.internals) {
+        // Note that the layout viewport is based on the minimum page scale.
+        // Thus, the minimum scale of 0.5 causes the layout viewport to become
+        // twice of what we would normally expect.
         window.internals.setPageScaleFactorLimits(0.5, 4.0);
         window.jsTestIsAsync = true;
         testRunner.dumpAsText();
         testRunner.waitUntilDone();
+        setPrintTestResultsLazily();
     }
 
     description("This test makes sure the window properties related to the\
         viewport remain correct under pinch-to-zoom.");
 
-    debug('===Unscaled===');
-    debug('');
-    shouldBe('window.innerWidth', '800');
-    shouldBe('window.innerHeight', '600');
+
+    function testInitialScale () {
+        debug('===Initial Scale===');
+        debug('');
+        shouldBe('window.innerWidth', '1600');
+        shouldBe('window.innerHeight', '1200');
+        shouldBe('internals.visualViewportWidth()', '1600');
+        shouldBe('internals.visualViewportHeight()', '1200');
+    }
+
+    function jsScrollTo(x, y) {
+        window.scrollTo(x, y);
+    }
+
+    function jsScrollBy(x, y) {
+        window.scrollBy(x, y);
+    }
+
+    function testScrolls(jsScroll) {
+        // Test that the layout and visual viewport viewport scroll.
+        jsScroll(100, 200);
+        shouldBe('window.scrollX', '100');
+        shouldBe('window.scrollY', '200');
+        shouldBe('internals.visualViewportScrollX()', '100');
+        shouldBe('internals.visualViewportScrollY()', '200');
+
+        // Test that the scroll doesn't bubble to the visual viewport.
+        jsScroll(1500, 1100);
+        shouldBe('window.scrollX', '400');
+        shouldBe('window.scrollY', '300');
+        shouldBe('internals.visualViewportScrollX()', '400');
+        shouldBe('internals.visualViewportScrollY()', '300');
+
+        // Reset.
+        window.scrollTo(0, 0);
+        shouldBe('window.scrollX', '0');
+        shouldBe('window.scrollY', '0');
+    }
 
     function testPinchedIn() {
         debug('');
         debug('===Pinch Zoom in to 2X===');
         debug('');
         window.internals.setPageScaleFactor(2.0);
-        shouldBe('window.innerWidth', '400');
-        shouldBe('window.innerHeight', '300');
+        // Test that the innerWidth, innerHeight, scrollX, scrollY are relative
+        // to the layout viewport after page scale.
+        shouldBe('window.innerWidth', '1600');
+        shouldBe('window.innerHeight', '1200');
         shouldBe('window.scrollX', '0');
         shouldBe('window.scrollY', '0');
 
-        window.scrollBy(10, 20);
-        shouldBe('window.scrollX', '10');
-        shouldBe('window.scrollY', '20');
-        window.scrollBy(1590, 1180);
-        shouldBe('window.scrollX', '1600');
-        shouldBe('window.scrollY', '1200');
-        window.scrollBy(-1600, -1200);
-        shouldBe('window.scrollX', '0');
-        shouldBe('window.scrollY', '0');
-        window.scrollTo(1600, 1200);
-        shouldBe('window.scrollX', '1600');
-        shouldBe('window.scrollY', '1200');
-        window.scrollTo(0, 0);
-        shouldBe('window.scrollX', '0');
-        shouldBe('window.scrollY', '0');
+        // Test that the visual viewport size changes after page scale.
+        shouldBe('internals.visualViewportWidth()', '400');
+        shouldBe('internals.visualViewportHeight()', '300');
+
+        debug('===ScrollBy===');
+        testScrolls(jsScrollBy);
+        debug('===ScrollTo===');
+        testScrolls(jsScrollTo);
     }
 
     function testMaximallyPinchedOut() {
@@ -68,86 +104,28 @@
         shouldBe('window.innerHeight', '1200');
         shouldBe('window.scrollX', '0');
         shouldBe('window.scrollY', '0');
+        shouldBe('internals.visualViewportWidth()', '1600');
+        shouldBe('internals.visualViewportHeight()', '1200');
 
-        window.scrollBy(10, 20);
-        shouldBe('window.scrollX', '10');
-        shouldBe('window.scrollY', '20');
-        window.scrollBy(390, 280);
-        shouldBe('window.scrollX', '400');
-        shouldBe('window.scrollY', '300');
-        window.scrollBy(-400, -300);
-        shouldBe('window.scrollX', '0');
-        shouldBe('window.scrollY', '0');
-        window.scrollTo(400, 300);
-        shouldBe('window.scrollX', '400');
-        shouldBe('window.scrollY', '300');
-        window.scrollTo(0, 0);
-        shouldBe('window.scrollX', '0');
-        shouldBe('window.scrollY', '0');
-    }
-
-    function testOnScroll() {
-        debug('');
-        debug('===Test OnScroll===');
-        debug('');
-        window.internals.setPageScaleFactor(1.0);
-        shouldBe('window.innerWidth', '800');
-        shouldBe('window.innerHeight', '600');
-        shouldBe('window.scrollX', '0');
-        shouldBe('window.scrollY', '0');
-
-        // First scroll scrolls only the outer viewport.
-        // Second scrolls the outer and the inner.
-        // Third scrolls only the inner.
-        var scrolls = [100, 400, 100];
-        var numScrollsReceived = 0;
-        var numRAFCalls = 0;
-
-        document.onscroll = function() {
-            if (numRAFCalls == 0)
-                return;
-
-            ++numScrollsReceived;
-            debug('PASS OnScroll called for scroll #' + numScrollsReceived);
-            if (numScrollsReceived < scrolls.length) {
-                var scrollAmount = scrolls[numScrollsReceived];
-                window.scrollBy(scrollAmount, 0);
-            } else if (numScrollsReceived == scrolls.length) {
-                // Make sure scrollTo that moves only the inner viewport also
-                // triggers a scroll event.
-                window.scrollTo(1200, 0);
-            } else {
-                debug('');
-                finishJSTest();
-            }
-        }
-
-        // Scroll events are fired right before RAF so this is a good place to
-        // make sure event was handled.
-        var failureSentinel = function() {
-            if (numRAFCalls == 0) {
-                window.scrollBy(scrolls[0], 0);
-            }else if (numRAFCalls > numScrollsReceived) {
-                testFailed("Failed to receive scroll event #" + (numScrollsReceived+1));
-                finishJSTest();
-            }
-            ++numRAFCalls;
-            window.requestAnimationFrame(failureSentinel);
-        }
-
-        window.requestAnimationFrame(failureSentinel);
+        debug('===ScrollBy===');
+        testScrolls(jsScrollBy);
+        debug('===ScrollTo===');
+        testScrolls(jsScrollTo);
     }
 
     function forceLayout() {
-        window.scrollTo(0, 0);
+        window.scrollX;
     }
 
     function runTests() {
         if (window.testRunner && window.internals) {
+            // TODO(ymalik): The call to setPageScaleFactorLimits should force
+            // layout. Fix that instead of forcing layout here.
             forceLayout();
+            testInitialScale();
             testPinchedIn();
             testMaximallyPinchedOut();
-            testOnScroll();
+            finishJSTest();
         }
     }
 
diff --git a/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling-expected.txt
deleted file mode 100644
index fe0ea0e..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This test ensures window.innerWidth/innerHeight return the size of the visual viewport in CSS pixels.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS window.innerWidth is Math.floor(originalWidth / scale)
-PASS window.innerHeight is Math.floor(originalHeight / scale)
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling.html b/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling.html
deleted file mode 100644
index a016857..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<html>
-    <script src="../../resources/js-test.js"></script>
-    <script>
-        description("This test ensures window.innerWidth/innerHeight return the size of the visual viewport in CSS pixels.");
-
-        var originalWidth = window.innerWidth;
-        var originalHeight = window.innerHeight;
-        var scale = 2;
-
-        if (window.internals)
-            window.internals.setPageScaleFactor(scale);
-
-        shouldBe("window.innerWidth", "Math.floor(originalWidth / scale)");
-        shouldBe("window.innerHeight", "Math.floor(originalHeight / scale)");
-    </script>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/pointerevents/mouse-pointer-preventdefault-expected.txt b/third_party/WebKit/LayoutTests/fast/events/pointerevents/mouse-pointer-preventdefault-expected.txt
index ab6db491..59686949 100644
--- a/third_party/WebKit/LayoutTests/fast/events/pointerevents/mouse-pointer-preventdefault-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/events/pointerevents/mouse-pointer-preventdefault-expected.txt
@@ -11,13 +11,18 @@
 3. target received mousemove
 4. target received mousedown
 5. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 6. target received mousedown
 7. target received mousemove
-8. target received mouseup
+8. target received mouseout
+9. target received mouseleave
+10. target received mouseover
+11. target received mouseenter
+12. target received mousemove
+13. target received mouseup
 - move outside target again -
-9. target received mouseout
-10. target received mouseleave
+14. target received mouseout
+15. target received mouseleave
 
 --- test with preventDefault on pointerdown ---
 - start with mouse outside target -
@@ -27,13 +32,18 @@
 3. target received mousemove
 4. target received mousedown
 5. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 6. target received mousedown
 7. target received mousemove
-8. target received mouseup
+8. target received mouseout
+9. target received mouseleave
+10. target received mouseover
+11. target received mouseenter
+12. target received mousemove
+13. target received mouseup
 - move outside target again -
-9. target received mouseout
-10. target received mouseleave
+14. target received mouseout
+15. target received mouseleave
 
 --- test with preventDefault on pointerup ---
 - start with mouse outside target -
@@ -43,13 +53,18 @@
 3. target received mousemove
 4. target received mousedown
 5. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 6. target received mousedown
 7. target received mousemove
-8. target received mouseup
+8. target received mouseout
+9. target received mouseleave
+10. target received mouseover
+11. target received mouseenter
+12. target received mousemove
+13. target received mouseup
 - move outside target again -
-9. target received mouseout
-10. target received mouseleave
+14. target received mouseout
+15. target received mouseleave
 
 --- test with preventDefault on pointerenter ---
 - start with mouse outside target -
@@ -59,13 +74,18 @@
 3. target received mousemove
 4. target received mousedown
 5. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 6. target received mousedown
 7. target received mousemove
-8. target received mouseup
+8. target received mouseout
+9. target received mouseleave
+10. target received mouseover
+11. target received mouseenter
+12. target received mousemove
+13. target received mouseup
 - move outside target again -
-9. target received mouseout
-10. target received mouseleave
+14. target received mouseout
+15. target received mouseleave
 
 --- test with preventDefault on pointerleave ---
 - start with mouse outside target -
@@ -75,13 +95,18 @@
 3. target received mousemove
 4. target received mousedown
 5. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 6. target received mousedown
 7. target received mousemove
-8. target received mouseup
+8. target received mouseout
+9. target received mouseleave
+10. target received mouseover
+11. target received mouseenter
+12. target received mousemove
+13. target received mouseup
 - move outside target again -
-9. target received mouseout
-10. target received mouseleave
+14. target received mouseout
+15. target received mouseleave
 
 --- test with preventDefault on pointerover ---
 - start with mouse outside target -
@@ -91,13 +116,18 @@
 3. target received mousemove
 4. target received mousedown
 5. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 6. target received mousedown
 7. target received mousemove
-8. target received mouseup
+8. target received mouseout
+9. target received mouseleave
+10. target received mouseover
+11. target received mouseenter
+12. target received mousemove
+13. target received mouseup
 - move outside target again -
-9. target received mouseout
-10. target received mouseleave
+14. target received mouseout
+15. target received mouseleave
 
 --- test with preventDefault on pointerout ---
 - start with mouse outside target -
@@ -107,13 +137,18 @@
 3. target received mousemove
 4. target received mousedown
 5. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 6. target received mousedown
 7. target received mousemove
-8. target received mouseup
+8. target received mouseout
+9. target received mouseleave
+10. target received mouseover
+11. target received mouseenter
+12. target received mousemove
+13. target received mouseup
 - move outside target again -
-9. target received mouseout
-10. target received mouseleave
+14. target received mouseout
+15. target received mouseleave
 
 --- test with preventDefault on pointermove ---
 - start with mouse outside target -
@@ -123,13 +158,18 @@
 3. target received mousemove
 4. target received mousedown
 5. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 6. target received mousedown
 7. target received mousemove
-8. target received mouseup
+8. target received mouseout
+9. target received mouseleave
+10. target received mouseover
+11. target received mouseenter
+12. target received mousemove
+13. target received mouseup
 - move outside target again -
-9. target received mouseout
-10. target received mouseleave
+14. target received mouseout
+15. target received mouseleave
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/fast/events/pointerevents/mouse-pointer-preventdefault.html b/third_party/WebKit/LayoutTests/fast/events/pointerevents/mouse-pointer-preventdefault.html
index 614d11a..5139784 100644
--- a/third_party/WebKit/LayoutTests/fast/events/pointerevents/mouse-pointer-preventdefault.html
+++ b/third_party/WebKit/LayoutTests/fast/events/pointerevents/mouse-pointer-preventdefault.html
@@ -66,13 +66,13 @@
     eventSender.mouseDown();
     eventSender.mouseUp();
 
-    debug("- drag & release within target -");
+    debug("- drag out of and into target & release within target -");
     eventSender.mouseDown();
     eventSender.mouseMoveTo(x2+5, y2+5);
+    eventSender.mouseMoveTo(x1, y1);
+    eventSender.mouseMoveTo(x2, y2);
     eventSender.mouseUp();
 
-    // TODO(mustaq): Add drag across target border after fixing crbug.com/356090.
-
     debug("- move outside target again -");
     eventSender.mouseMoveTo(x1, y1);
 
diff --git a/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-center.html b/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-center.html
new file mode 100644
index 0000000..52328c9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-center.html
@@ -0,0 +1,63 @@
+<style>
+td {
+  border: 1px solid black;
+  width: 120px;
+  height: 120px;
+}
+td div {
+    height: 100%;
+    width: 100%;
+}
+th {
+    padding: 5px;
+}
+</style>
+
+<table border="1">
+    <tr><th colspan="5">text-align: center</th></tr>
+    <tr><th colspan="2" rowspan="2">&nbsp;</th><th colspan="3">-webkit-writing-mode</th></tr>
+    <tr><th>horizontal-tb</th><th>vertical-lr</th><th>vertical-rl</th></tr>
+    <tr>
+        <th rowspan="4">direction</th>
+        <th>ltr</th>
+        <td>
+            <div style="-webkit-writing-mode:horizontal-tb; direction:ltr">
+                <details style="text-align:center"><summary>summary</summary></details>
+                <details style="text-align:center" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-lr; direction:ltr">
+                <details style="text-align:center"><summary>summary</summary></details>
+                <details style="text-align:center" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-rl; direction:ltr">
+                <details style="text-align:center"><summary>summary</summary></details>
+                <details style="text-align:center" open><summary>summary</summary></details>
+            </div>
+        </td>
+    </tr>
+    <tr>
+        <th>rtl</th>
+        <td>
+            <div style="-webkit-writing-mode:horizontal-tb; direction:rtl">
+                <details style="text-align:center"><summary>summary</summary></details>
+                <details style="text-align:center" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-lr; direction:rtl">
+                <details style="text-align:center"><summary>summary</summary></details>
+                <details style="text-align:center" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-rl; direction:rtl">
+                <details style="text-align:center"><summary>summary</summary></details>
+                <details style="text-align:center" open><summary>summary</summary></details>
+            </div>
+        </td>
+    </tr>
+</table>
diff --git a/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-left.html b/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-left.html
new file mode 100644
index 0000000..f44f37c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-left.html
@@ -0,0 +1,63 @@
+<style>
+td {
+  border: 1px solid black;
+  width: 120px;
+  height: 120px;
+}
+td div {
+    height: 100%;
+    width: 100%;
+}
+th {
+    padding: 5px;
+}
+</style>
+
+<table border="1">
+    <tr><th colspan="5">text-align: left</th></tr>
+    <tr><th colspan="2" rowspan="2">&nbsp;</th><th colspan="3">-webkit-writing-mode</th></tr>
+    <tr><th>horizontal-tb</th><th>vertical-lr</th><th>vertical-rl</th></tr>
+    <tr>
+        <th rowspan="4">direction</th>
+        <th>ltr</th>
+        <td>
+            <div style="-webkit-writing-mode:horizontal-tb; direction:ltr">
+                <details style="text-align:left"><summary>summary</summary></details>
+                <details style="text-align:left" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-lr; direction:ltr">
+                <details style="text-align:left"><summary>summary</summary></details>
+                <details style="text-align:left" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-rl; direction:ltr">
+                <details style="text-align:left"><summary>summary</summary></details>
+                <details style="text-align:left" open><summary>summary</summary></details>
+            </div>
+        </td>
+    </tr>
+    <tr>
+        <th>rtl</th>
+        <td>
+            <div style="-webkit-writing-mode:horizontal-tb; direction:rtl">
+                <details style="text-align:left"><summary>summary</summary></details>
+                <details style="text-align:left" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-lr; direction:rtl">
+                <details style="text-align:left"><summary>summary</summary></details>
+                <details style="text-align:left" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-rl; direction:rtl">
+                <details style="text-align:left"><summary>summary</summary></details>
+                <details style="text-align:left" open><summary>summary</summary></details>
+            </div>
+        </td>
+    </tr>
+</table>
diff --git a/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-right.html b/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-right.html
new file mode 100644
index 0000000..00e3946
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/html/details-writing-mode-align-right.html
@@ -0,0 +1,63 @@
+<style>
+td {
+  border: 1px solid black;
+  width: 120px;
+  height: 120px;
+}
+td div {
+    height: 100%;
+    width: 100%;
+}
+th {
+    padding: 5px;
+}
+</style>
+
+<table border="1">
+    <tr><th colspan="5">text-align: right</th></tr>
+    <tr><th colspan="2" rowspan="2">&nbsp;</th><th colspan="3">-webkit-writing-mode</th></tr>
+    <tr><th>horizontal-tb</th><th>vertical-lr</th><th>vertical-rl</th></tr>
+    <tr>
+        <th rowspan="4">direction</th>
+        <th>ltr</th>
+        <td>
+            <div style="-webkit-writing-mode:horizontal-tb; direction:ltr">
+                <details style="text-align:right"><summary>summary</summary></details>
+                <details style="text-align:right" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-lr; direction:ltr">
+                <details style="text-align:right"><summary>summary</summary></details>
+                <details style="text-align:right" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-rl; direction:ltr">
+                <details style="text-align:right"><summary>summary</summary></details>
+                <details style="text-align:right" open><summary>summary</summary></details>
+            </div>
+        </td>
+    </tr>
+    <tr>
+        <th>rtl</th>
+        <td>
+            <div style="-webkit-writing-mode:horizontal-tb; direction:rtl">
+                <details style="text-align:right"><summary>summary</summary></details>
+                <details style="text-align:right" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-lr; direction:rtl">
+                <details style="text-align:right"><summary>summary</summary></details>
+                <details style="text-align:right" open><summary>summary</summary></details>
+            </div>
+        </td>
+        <td>
+            <div style="-webkit-writing-mode:vertical-rl; direction:rtl">
+                <details style="text-align:right"><summary>summary</summary></details>
+                <details style="text-align:right" open><summary>summary</summary></details>
+            </div>
+        </td>
+    </tr>
+</table>
diff --git a/third_party/WebKit/LayoutTests/fast/html/details-writing-mode.html b/third_party/WebKit/LayoutTests/fast/html/details-writing-mode.html
index 00fc2f4..9bbd7572 100644
--- a/third_party/WebKit/LayoutTests/fast/html/details-writing-mode.html
+++ b/third_party/WebKit/LayoutTests/fast/html/details-writing-mode.html
@@ -62,155 +62,3 @@
         </td>
     </tr>
 </table>
-
-<br>
-<table border="1">
-    <tr><th colspan="5">text-align: left</th></tr>
-    <tr><th colspan="2" rowspan="2">&nbsp;</th><th colspan="3">-webkit-writing-mode</th></tr>
-    <tr><th>horizontal-tb</th><th>vertical-lr</th><th>vertical-rl</th></tr>
-    <tr>
-        <th rowspan="4">direction</th>
-        <th>ltr</th>
-        <td>
-            <div style="-webkit-writing-mode:horizontal-tb; direction:ltr">
-                <details style="text-align:left"><summary>summary</summary></details>
-                <details style="text-align:left" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-lr; direction:ltr">
-                <details style="text-align:left"><summary>summary</summary></details>
-                <details style="text-align:left" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-rl; direction:ltr">
-                <details style="text-align:left"><summary>summary</summary></details>
-                <details style="text-align:left" open><summary>summary</summary></details>
-            </div>
-        </td>
-    </tr>
-    <tr>
-        <th>rtl</th>
-        <td>
-            <div style="-webkit-writing-mode:horizontal-tb; direction:rtl">
-                <details style="text-align:left"><summary>summary</summary></details>
-                <details style="text-align:left" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-lr; direction:rtl">
-                <details style="text-align:left"><summary>summary</summary></details>
-                <details style="text-align:left" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-rl; direction:rtl">
-                <details style="text-align:left"><summary>summary</summary></details>
-                <details style="text-align:left" open><summary>summary</summary></details>
-            </div>
-        </td>
-    </tr>
-</table>
-
-
-<br>
-<table border="1">
-    <tr><th colspan="5">text-align: center</th></tr>
-    <tr><th colspan="2" rowspan="2">&nbsp;</th><th colspan="3">-webkit-writing-mode</th></tr>
-    <tr><th>horizontal-tb</th><th>vertical-lr</th><th>vertical-rl</th></tr>
-    <tr>
-        <th rowspan="4">direction</th>
-        <th>ltr</th>
-        <td>
-            <div style="-webkit-writing-mode:horizontal-tb; direction:ltr">
-                <details style="text-align:center"><summary>summary</summary></details>
-                <details style="text-align:center" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-lr; direction:ltr">
-                <details style="text-align:center"><summary>summary</summary></details>
-                <details style="text-align:center" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-rl; direction:ltr">
-                <details style="text-align:center"><summary>summary</summary></details>
-                <details style="text-align:center" open><summary>summary</summary></details>
-            </div>
-        </td>
-    </tr>
-    <tr>
-        <th>rtl</th>
-        <td>
-            <div style="-webkit-writing-mode:horizontal-tb; direction:rtl">
-                <details style="text-align:center"><summary>summary</summary></details>
-                <details style="text-align:center" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-lr; direction:rtl">
-                <details style="text-align:center"><summary>summary</summary></details>
-                <details style="text-align:center" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-rl; direction:rtl">
-                <details style="text-align:center"><summary>summary</summary></details>
-                <details style="text-align:center" open><summary>summary</summary></details>
-            </div>
-        </td>
-    </tr>
-</table>
-
-
-<br>
-<table border="1">
-    <tr><th colspan="5">text-align: right</th></tr>
-    <tr><th colspan="2" rowspan="2">&nbsp;</th><th colspan="3">-webkit-writing-mode</th></tr>
-    <tr><th>horizontal-tb</th><th>vertical-lr</th><th>vertical-rl</th></tr>
-    <tr>
-        <th rowspan="4">direction</th>
-        <th>ltr</th>
-        <td>
-            <div style="-webkit-writing-mode:horizontal-tb; direction:ltr">
-                <details style="text-align:right"><summary>summary</summary></details>
-                <details style="text-align:right" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-lr; direction:ltr">
-                <details style="text-align:right"><summary>summary</summary></details>
-                <details style="text-align:right" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-rl; direction:ltr">
-                <details style="text-align:right"><summary>summary</summary></details>
-                <details style="text-align:right" open><summary>summary</summary></details>
-            </div>
-        </td>
-    </tr>
-    <tr>
-        <th>rtl</th>
-        <td>
-            <div style="-webkit-writing-mode:horizontal-tb; direction:rtl">
-                <details style="text-align:right"><summary>summary</summary></details>
-                <details style="text-align:right" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-lr; direction:rtl">
-                <details style="text-align:right"><summary>summary</summary></details>
-                <details style="text-align:right" open><summary>summary</summary></details>
-            </div>
-        </td>
-        <td>
-            <div style="-webkit-writing-mode:vertical-rl; direction:rtl">
-                <details style="text-align:right"><summary>summary</summary></details>
-                <details style="text-align:right" open><summary>summary</summary></details>
-            </div>
-        </td>
-    </tr>
-</table>
diff --git a/third_party/WebKit/LayoutTests/fast/images/gif-loop-count-expected.png b/third_party/WebKit/LayoutTests/fast/images/gif-loop-count-expected.png
new file mode 100644
index 0000000..8113b17f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/images/gif-loop-count-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/js/reserved-words-as-property-expected.txt b/third_party/WebKit/LayoutTests/fast/js/reserved-words-as-property-expected.txt
deleted file mode 100644
index 331fd95..0000000
--- a/third_party/WebKit/LayoutTests/fast/js/reserved-words-as-property-expected.txt
+++ /dev/null
@@ -1,2206 +0,0 @@
-Tests to ensure that we can use ES reserved words as property names.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS var true; true threw exception SyntaxError: Unexpected token true.
-PASS (function(){var true; true}); true threw exception SyntaxError: Unexpected token true.
-PASS var true = 42; true === 42 threw exception SyntaxError: Unexpected token true.
-PASS (function(){var true = 42; true === 42}); true threw exception SyntaxError: Unexpected token true.
-PASS function g(true){  }; true threw exception SyntaxError: Unexpected token true.
-PASS (function(){function g(true){  }; true}); true threw exception SyntaxError: Unexpected token true.
-PASS /true/.test(function g(true){  }) threw exception SyntaxError: Unexpected token true.
-PASS (function(){/true/.test(function g(true){  })}); true threw exception SyntaxError: Unexpected token true.
-PASS try{}catch(true){}; true threw exception SyntaxError: Unexpected token true.
-PASS (function(){try{}catch(true){}; true}); true threw exception SyntaxError: Unexpected token true.
-PASS function true(){  }; true threw exception SyntaxError: Unexpected token true.
-PASS (function(){function true(){  }; true}); true threw exception SyntaxError: Unexpected token true.
-PASS ({ "true": 42 }.true === 42) is true
-PASS (function(){({ "true": 42 }.true === 42)}); true is true
-PASS ({ true: 42 }.true === 42) is true
-PASS (function(){({ true: 42 }.true === 42)}); true is true
-PASS ({ get true(){}, set true(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get true(){}, set true(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var true; true threw exception SyntaxError: Unexpected token true.
-PASS (function(){"use strict";var true; true}); true threw exception SyntaxError: Unexpected token true.
-PASS "use strict";var true = 42; true === 42 threw exception SyntaxError: Unexpected token true.
-PASS (function(){"use strict";var true = 42; true === 42}); true threw exception SyntaxError: Unexpected token true.
-PASS "use strict";function g(true){ "use strict"; }; true threw exception SyntaxError: Unexpected token true.
-PASS (function(){"use strict";function g(true){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token true.
-PASS "use strict";/true/.test(function g(true){ "use strict"; }) threw exception SyntaxError: Unexpected token true.
-PASS (function(){"use strict";/true/.test(function g(true){ "use strict"; })}); true threw exception SyntaxError: Unexpected token true.
-PASS "use strict";try{}catch(true){}; true threw exception SyntaxError: Unexpected token true.
-PASS (function(){"use strict";try{}catch(true){}; true}); true threw exception SyntaxError: Unexpected token true.
-PASS "use strict";function true(){ "use strict"; }; true threw exception SyntaxError: Unexpected token true.
-PASS (function(){"use strict";function true(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token true.
-PASS "use strict";({ "true": 42 }.true === 42) is true
-PASS (function(){"use strict";({ "true": 42 }.true === 42)}); true is true
-PASS "use strict";({ true: 42 }.true === 42) is true
-PASS (function(){"use strict";({ true: 42 }.true === 42)}); true is true
-PASS "use strict";({ get true(){}, set true(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get true(){}, set true(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var false; true threw exception SyntaxError: Unexpected token false.
-PASS (function(){var false; true}); true threw exception SyntaxError: Unexpected token false.
-PASS var false = 42; false === 42 threw exception SyntaxError: Unexpected token false.
-PASS (function(){var false = 42; false === 42}); true threw exception SyntaxError: Unexpected token false.
-PASS function g(false){  }; true threw exception SyntaxError: Unexpected token false.
-PASS (function(){function g(false){  }; true}); true threw exception SyntaxError: Unexpected token false.
-PASS /false/.test(function g(false){  }) threw exception SyntaxError: Unexpected token false.
-PASS (function(){/false/.test(function g(false){  })}); true threw exception SyntaxError: Unexpected token false.
-PASS try{}catch(false){}; true threw exception SyntaxError: Unexpected token false.
-PASS (function(){try{}catch(false){}; true}); true threw exception SyntaxError: Unexpected token false.
-PASS function false(){  }; true threw exception SyntaxError: Unexpected token false.
-PASS (function(){function false(){  }; true}); true threw exception SyntaxError: Unexpected token false.
-PASS ({ "false": 42 }.false === 42) is true
-PASS (function(){({ "false": 42 }.false === 42)}); true is true
-PASS ({ false: 42 }.false === 42) is true
-PASS (function(){({ false: 42 }.false === 42)}); true is true
-PASS ({ get false(){}, set false(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get false(){}, set false(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var false; true threw exception SyntaxError: Unexpected token false.
-PASS (function(){"use strict";var false; true}); true threw exception SyntaxError: Unexpected token false.
-PASS "use strict";var false = 42; false === 42 threw exception SyntaxError: Unexpected token false.
-PASS (function(){"use strict";var false = 42; false === 42}); true threw exception SyntaxError: Unexpected token false.
-PASS "use strict";function g(false){ "use strict"; }; true threw exception SyntaxError: Unexpected token false.
-PASS (function(){"use strict";function g(false){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token false.
-PASS "use strict";/false/.test(function g(false){ "use strict"; }) threw exception SyntaxError: Unexpected token false.
-PASS (function(){"use strict";/false/.test(function g(false){ "use strict"; })}); true threw exception SyntaxError: Unexpected token false.
-PASS "use strict";try{}catch(false){}; true threw exception SyntaxError: Unexpected token false.
-PASS (function(){"use strict";try{}catch(false){}; true}); true threw exception SyntaxError: Unexpected token false.
-PASS "use strict";function false(){ "use strict"; }; true threw exception SyntaxError: Unexpected token false.
-PASS (function(){"use strict";function false(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token false.
-PASS "use strict";({ "false": 42 }.false === 42) is true
-PASS (function(){"use strict";({ "false": 42 }.false === 42)}); true is true
-PASS "use strict";({ false: 42 }.false === 42) is true
-PASS (function(){"use strict";({ false: 42 }.false === 42)}); true is true
-PASS "use strict";({ get false(){}, set false(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get false(){}, set false(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var null; true threw exception SyntaxError: Unexpected token null.
-PASS (function(){var null; true}); true threw exception SyntaxError: Unexpected token null.
-PASS var null = 42; null === 42 threw exception SyntaxError: Unexpected token null.
-PASS (function(){var null = 42; null === 42}); true threw exception SyntaxError: Unexpected token null.
-PASS function g(null){  }; true threw exception SyntaxError: Unexpected token null.
-PASS (function(){function g(null){  }; true}); true threw exception SyntaxError: Unexpected token null.
-PASS /null/.test(function g(null){  }) threw exception SyntaxError: Unexpected token null.
-PASS (function(){/null/.test(function g(null){  })}); true threw exception SyntaxError: Unexpected token null.
-PASS try{}catch(null){}; true threw exception SyntaxError: Unexpected token null.
-PASS (function(){try{}catch(null){}; true}); true threw exception SyntaxError: Unexpected token null.
-PASS function null(){  }; true threw exception SyntaxError: Unexpected token null.
-PASS (function(){function null(){  }; true}); true threw exception SyntaxError: Unexpected token null.
-PASS ({ "null": 42 }.null === 42) is true
-PASS (function(){({ "null": 42 }.null === 42)}); true is true
-PASS ({ null: 42 }.null === 42) is true
-PASS (function(){({ null: 42 }.null === 42)}); true is true
-PASS ({ get null(){}, set null(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get null(){}, set null(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var null; true threw exception SyntaxError: Unexpected token null.
-PASS (function(){"use strict";var null; true}); true threw exception SyntaxError: Unexpected token null.
-PASS "use strict";var null = 42; null === 42 threw exception SyntaxError: Unexpected token null.
-PASS (function(){"use strict";var null = 42; null === 42}); true threw exception SyntaxError: Unexpected token null.
-PASS "use strict";function g(null){ "use strict"; }; true threw exception SyntaxError: Unexpected token null.
-PASS (function(){"use strict";function g(null){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token null.
-PASS "use strict";/null/.test(function g(null){ "use strict"; }) threw exception SyntaxError: Unexpected token null.
-PASS (function(){"use strict";/null/.test(function g(null){ "use strict"; })}); true threw exception SyntaxError: Unexpected token null.
-PASS "use strict";try{}catch(null){}; true threw exception SyntaxError: Unexpected token null.
-PASS (function(){"use strict";try{}catch(null){}; true}); true threw exception SyntaxError: Unexpected token null.
-PASS "use strict";function null(){ "use strict"; }; true threw exception SyntaxError: Unexpected token null.
-PASS (function(){"use strict";function null(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token null.
-PASS "use strict";({ "null": 42 }.null === 42) is true
-PASS (function(){"use strict";({ "null": 42 }.null === 42)}); true is true
-PASS "use strict";({ null: 42 }.null === 42) is true
-PASS (function(){"use strict";({ null: 42 }.null === 42)}); true is true
-PASS "use strict";({ get null(){}, set null(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get null(){}, set null(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var break; true threw exception SyntaxError: Unexpected token break.
-PASS (function(){var break; true}); true threw exception SyntaxError: Unexpected token break.
-PASS var break = 42; break === 42 threw exception SyntaxError: Unexpected token break.
-PASS (function(){var break = 42; break === 42}); true threw exception SyntaxError: Unexpected token break.
-PASS function g(break){  }; true threw exception SyntaxError: Unexpected token break.
-PASS (function(){function g(break){  }; true}); true threw exception SyntaxError: Unexpected token break.
-PASS /break/.test(function g(break){  }) threw exception SyntaxError: Unexpected token break.
-PASS (function(){/break/.test(function g(break){  })}); true threw exception SyntaxError: Unexpected token break.
-PASS try{}catch(break){}; true threw exception SyntaxError: Unexpected token break.
-PASS (function(){try{}catch(break){}; true}); true threw exception SyntaxError: Unexpected token break.
-PASS function break(){  }; true threw exception SyntaxError: Unexpected token break.
-PASS (function(){function break(){  }; true}); true threw exception SyntaxError: Unexpected token break.
-PASS ({ "break": 42 }.break === 42) is true
-PASS (function(){({ "break": 42 }.break === 42)}); true is true
-PASS ({ break: 42 }.break === 42) is true
-PASS (function(){({ break: 42 }.break === 42)}); true is true
-PASS ({ get break(){}, set break(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get break(){}, set break(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var break; true threw exception SyntaxError: Unexpected token break.
-PASS (function(){"use strict";var break; true}); true threw exception SyntaxError: Unexpected token break.
-PASS "use strict";var break = 42; break === 42 threw exception SyntaxError: Unexpected token break.
-PASS (function(){"use strict";var break = 42; break === 42}); true threw exception SyntaxError: Unexpected token break.
-PASS "use strict";function g(break){ "use strict"; }; true threw exception SyntaxError: Unexpected token break.
-PASS (function(){"use strict";function g(break){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token break.
-PASS "use strict";/break/.test(function g(break){ "use strict"; }) threw exception SyntaxError: Unexpected token break.
-PASS (function(){"use strict";/break/.test(function g(break){ "use strict"; })}); true threw exception SyntaxError: Unexpected token break.
-PASS "use strict";try{}catch(break){}; true threw exception SyntaxError: Unexpected token break.
-PASS (function(){"use strict";try{}catch(break){}; true}); true threw exception SyntaxError: Unexpected token break.
-PASS "use strict";function break(){ "use strict"; }; true threw exception SyntaxError: Unexpected token break.
-PASS (function(){"use strict";function break(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token break.
-PASS "use strict";({ "break": 42 }.break === 42) is true
-PASS (function(){"use strict";({ "break": 42 }.break === 42)}); true is true
-PASS "use strict";({ break: 42 }.break === 42) is true
-PASS (function(){"use strict";({ break: 42 }.break === 42)}); true is true
-PASS "use strict";({ get break(){}, set break(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get break(){}, set break(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var case; true threw exception SyntaxError: Unexpected token case.
-PASS (function(){var case; true}); true threw exception SyntaxError: Unexpected token case.
-PASS var case = 42; case === 42 threw exception SyntaxError: Unexpected token case.
-PASS (function(){var case = 42; case === 42}); true threw exception SyntaxError: Unexpected token case.
-PASS function g(case){  }; true threw exception SyntaxError: Unexpected token case.
-PASS (function(){function g(case){  }; true}); true threw exception SyntaxError: Unexpected token case.
-PASS /case/.test(function g(case){  }) threw exception SyntaxError: Unexpected token case.
-PASS (function(){/case/.test(function g(case){  })}); true threw exception SyntaxError: Unexpected token case.
-PASS try{}catch(case){}; true threw exception SyntaxError: Unexpected token case.
-PASS (function(){try{}catch(case){}; true}); true threw exception SyntaxError: Unexpected token case.
-PASS function case(){  }; true threw exception SyntaxError: Unexpected token case.
-PASS (function(){function case(){  }; true}); true threw exception SyntaxError: Unexpected token case.
-PASS ({ "case": 42 }.case === 42) is true
-PASS (function(){({ "case": 42 }.case === 42)}); true is true
-PASS ({ case: 42 }.case === 42) is true
-PASS (function(){({ case: 42 }.case === 42)}); true is true
-PASS ({ get case(){}, set case(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get case(){}, set case(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var case; true threw exception SyntaxError: Unexpected token case.
-PASS (function(){"use strict";var case; true}); true threw exception SyntaxError: Unexpected token case.
-PASS "use strict";var case = 42; case === 42 threw exception SyntaxError: Unexpected token case.
-PASS (function(){"use strict";var case = 42; case === 42}); true threw exception SyntaxError: Unexpected token case.
-PASS "use strict";function g(case){ "use strict"; }; true threw exception SyntaxError: Unexpected token case.
-PASS (function(){"use strict";function g(case){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token case.
-PASS "use strict";/case/.test(function g(case){ "use strict"; }) threw exception SyntaxError: Unexpected token case.
-PASS (function(){"use strict";/case/.test(function g(case){ "use strict"; })}); true threw exception SyntaxError: Unexpected token case.
-PASS "use strict";try{}catch(case){}; true threw exception SyntaxError: Unexpected token case.
-PASS (function(){"use strict";try{}catch(case){}; true}); true threw exception SyntaxError: Unexpected token case.
-PASS "use strict";function case(){ "use strict"; }; true threw exception SyntaxError: Unexpected token case.
-PASS (function(){"use strict";function case(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token case.
-PASS "use strict";({ "case": 42 }.case === 42) is true
-PASS (function(){"use strict";({ "case": 42 }.case === 42)}); true is true
-PASS "use strict";({ case: 42 }.case === 42) is true
-PASS (function(){"use strict";({ case: 42 }.case === 42)}); true is true
-PASS "use strict";({ get case(){}, set case(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get case(){}, set case(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var catch; true threw exception SyntaxError: Unexpected token catch.
-PASS (function(){var catch; true}); true threw exception SyntaxError: Unexpected token catch.
-PASS var catch = 42; catch === 42 threw exception SyntaxError: Unexpected token catch.
-PASS (function(){var catch = 42; catch === 42}); true threw exception SyntaxError: Unexpected token catch.
-PASS function g(catch){  }; true threw exception SyntaxError: Unexpected token catch.
-PASS (function(){function g(catch){  }; true}); true threw exception SyntaxError: Unexpected token catch.
-PASS /catch/.test(function g(catch){  }) threw exception SyntaxError: Unexpected token catch.
-PASS (function(){/catch/.test(function g(catch){  })}); true threw exception SyntaxError: Unexpected token catch.
-PASS try{}catch(catch){}; true threw exception SyntaxError: Unexpected token catch.
-PASS (function(){try{}catch(catch){}; true}); true threw exception SyntaxError: Unexpected token catch.
-PASS function catch(){  }; true threw exception SyntaxError: Unexpected token catch.
-PASS (function(){function catch(){  }; true}); true threw exception SyntaxError: Unexpected token catch.
-PASS ({ "catch": 42 }.catch === 42) is true
-PASS (function(){({ "catch": 42 }.catch === 42)}); true is true
-PASS ({ catch: 42 }.catch === 42) is true
-PASS (function(){({ catch: 42 }.catch === 42)}); true is true
-PASS ({ get catch(){}, set catch(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get catch(){}, set catch(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var catch; true threw exception SyntaxError: Unexpected token catch.
-PASS (function(){"use strict";var catch; true}); true threw exception SyntaxError: Unexpected token catch.
-PASS "use strict";var catch = 42; catch === 42 threw exception SyntaxError: Unexpected token catch.
-PASS (function(){"use strict";var catch = 42; catch === 42}); true threw exception SyntaxError: Unexpected token catch.
-PASS "use strict";function g(catch){ "use strict"; }; true threw exception SyntaxError: Unexpected token catch.
-PASS (function(){"use strict";function g(catch){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token catch.
-PASS "use strict";/catch/.test(function g(catch){ "use strict"; }) threw exception SyntaxError: Unexpected token catch.
-PASS (function(){"use strict";/catch/.test(function g(catch){ "use strict"; })}); true threw exception SyntaxError: Unexpected token catch.
-PASS "use strict";try{}catch(catch){}; true threw exception SyntaxError: Unexpected token catch.
-PASS (function(){"use strict";try{}catch(catch){}; true}); true threw exception SyntaxError: Unexpected token catch.
-PASS "use strict";function catch(){ "use strict"; }; true threw exception SyntaxError: Unexpected token catch.
-PASS (function(){"use strict";function catch(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token catch.
-PASS "use strict";({ "catch": 42 }.catch === 42) is true
-PASS (function(){"use strict";({ "catch": 42 }.catch === 42)}); true is true
-PASS "use strict";({ catch: 42 }.catch === 42) is true
-PASS (function(){"use strict";({ catch: 42 }.catch === 42)}); true is true
-PASS "use strict";({ get catch(){}, set catch(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get catch(){}, set catch(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var continue; true threw exception SyntaxError: Unexpected token continue.
-PASS (function(){var continue; true}); true threw exception SyntaxError: Unexpected token continue.
-PASS var continue = 42; continue === 42 threw exception SyntaxError: Unexpected token continue.
-PASS (function(){var continue = 42; continue === 42}); true threw exception SyntaxError: Unexpected token continue.
-PASS function g(continue){  }; true threw exception SyntaxError: Unexpected token continue.
-PASS (function(){function g(continue){  }; true}); true threw exception SyntaxError: Unexpected token continue.
-PASS /continue/.test(function g(continue){  }) threw exception SyntaxError: Unexpected token continue.
-PASS (function(){/continue/.test(function g(continue){  })}); true threw exception SyntaxError: Unexpected token continue.
-PASS try{}catch(continue){}; true threw exception SyntaxError: Unexpected token continue.
-PASS (function(){try{}catch(continue){}; true}); true threw exception SyntaxError: Unexpected token continue.
-PASS function continue(){  }; true threw exception SyntaxError: Unexpected token continue.
-PASS (function(){function continue(){  }; true}); true threw exception SyntaxError: Unexpected token continue.
-PASS ({ "continue": 42 }.continue === 42) is true
-PASS (function(){({ "continue": 42 }.continue === 42)}); true is true
-PASS ({ continue: 42 }.continue === 42) is true
-PASS (function(){({ continue: 42 }.continue === 42)}); true is true
-PASS ({ get continue(){}, set continue(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get continue(){}, set continue(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var continue; true threw exception SyntaxError: Unexpected token continue.
-PASS (function(){"use strict";var continue; true}); true threw exception SyntaxError: Unexpected token continue.
-PASS "use strict";var continue = 42; continue === 42 threw exception SyntaxError: Unexpected token continue.
-PASS (function(){"use strict";var continue = 42; continue === 42}); true threw exception SyntaxError: Unexpected token continue.
-PASS "use strict";function g(continue){ "use strict"; }; true threw exception SyntaxError: Unexpected token continue.
-PASS (function(){"use strict";function g(continue){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token continue.
-PASS "use strict";/continue/.test(function g(continue){ "use strict"; }) threw exception SyntaxError: Unexpected token continue.
-PASS (function(){"use strict";/continue/.test(function g(continue){ "use strict"; })}); true threw exception SyntaxError: Unexpected token continue.
-PASS "use strict";try{}catch(continue){}; true threw exception SyntaxError: Unexpected token continue.
-PASS (function(){"use strict";try{}catch(continue){}; true}); true threw exception SyntaxError: Unexpected token continue.
-PASS "use strict";function continue(){ "use strict"; }; true threw exception SyntaxError: Unexpected token continue.
-PASS (function(){"use strict";function continue(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token continue.
-PASS "use strict";({ "continue": 42 }.continue === 42) is true
-PASS (function(){"use strict";({ "continue": 42 }.continue === 42)}); true is true
-PASS "use strict";({ continue: 42 }.continue === 42) is true
-PASS (function(){"use strict";({ continue: 42 }.continue === 42)}); true is true
-PASS "use strict";({ get continue(){}, set continue(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get continue(){}, set continue(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var debugger; true threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){var debugger; true}); true threw exception SyntaxError: Unexpected token debugger.
-PASS var debugger = 42; debugger === 42 threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){var debugger = 42; debugger === 42}); true threw exception SyntaxError: Unexpected token debugger.
-PASS function g(debugger){  }; true threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){function g(debugger){  }; true}); true threw exception SyntaxError: Unexpected token debugger.
-PASS /debugger/.test(function g(debugger){  }) threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){/debugger/.test(function g(debugger){  })}); true threw exception SyntaxError: Unexpected token debugger.
-PASS try{}catch(debugger){}; true threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){try{}catch(debugger){}; true}); true threw exception SyntaxError: Unexpected token debugger.
-PASS function debugger(){  }; true threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){function debugger(){  }; true}); true threw exception SyntaxError: Unexpected token debugger.
-PASS ({ "debugger": 42 }.debugger === 42) is true
-PASS (function(){({ "debugger": 42 }.debugger === 42)}); true is true
-PASS ({ debugger: 42 }.debugger === 42) is true
-PASS (function(){({ debugger: 42 }.debugger === 42)}); true is true
-PASS ({ get debugger(){}, set debugger(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get debugger(){}, set debugger(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var debugger; true threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){"use strict";var debugger; true}); true threw exception SyntaxError: Unexpected token debugger.
-PASS "use strict";var debugger = 42; debugger === 42 threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){"use strict";var debugger = 42; debugger === 42}); true threw exception SyntaxError: Unexpected token debugger.
-PASS "use strict";function g(debugger){ "use strict"; }; true threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){"use strict";function g(debugger){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token debugger.
-PASS "use strict";/debugger/.test(function g(debugger){ "use strict"; }) threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){"use strict";/debugger/.test(function g(debugger){ "use strict"; })}); true threw exception SyntaxError: Unexpected token debugger.
-PASS "use strict";try{}catch(debugger){}; true threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){"use strict";try{}catch(debugger){}; true}); true threw exception SyntaxError: Unexpected token debugger.
-PASS "use strict";function debugger(){ "use strict"; }; true threw exception SyntaxError: Unexpected token debugger.
-PASS (function(){"use strict";function debugger(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token debugger.
-PASS "use strict";({ "debugger": 42 }.debugger === 42) is true
-PASS (function(){"use strict";({ "debugger": 42 }.debugger === 42)}); true is true
-PASS "use strict";({ debugger: 42 }.debugger === 42) is true
-PASS (function(){"use strict";({ debugger: 42 }.debugger === 42)}); true is true
-PASS "use strict";({ get debugger(){}, set debugger(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get debugger(){}, set debugger(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var default; true threw exception SyntaxError: Unexpected token default.
-PASS (function(){var default; true}); true threw exception SyntaxError: Unexpected token default.
-PASS var default = 42; default === 42 threw exception SyntaxError: Unexpected token default.
-PASS (function(){var default = 42; default === 42}); true threw exception SyntaxError: Unexpected token default.
-PASS function g(default){  }; true threw exception SyntaxError: Unexpected token default.
-PASS (function(){function g(default){  }; true}); true threw exception SyntaxError: Unexpected token default.
-PASS /default/.test(function g(default){  }) threw exception SyntaxError: Unexpected token default.
-PASS (function(){/default/.test(function g(default){  })}); true threw exception SyntaxError: Unexpected token default.
-PASS try{}catch(default){}; true threw exception SyntaxError: Unexpected token default.
-PASS (function(){try{}catch(default){}; true}); true threw exception SyntaxError: Unexpected token default.
-PASS function default(){  }; true threw exception SyntaxError: Unexpected token default.
-PASS (function(){function default(){  }; true}); true threw exception SyntaxError: Unexpected token default.
-PASS ({ "default": 42 }.default === 42) is true
-PASS (function(){({ "default": 42 }.default === 42)}); true is true
-PASS ({ default: 42 }.default === 42) is true
-PASS (function(){({ default: 42 }.default === 42)}); true is true
-PASS ({ get default(){}, set default(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get default(){}, set default(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var default; true threw exception SyntaxError: Unexpected token default.
-PASS (function(){"use strict";var default; true}); true threw exception SyntaxError: Unexpected token default.
-PASS "use strict";var default = 42; default === 42 threw exception SyntaxError: Unexpected token default.
-PASS (function(){"use strict";var default = 42; default === 42}); true threw exception SyntaxError: Unexpected token default.
-PASS "use strict";function g(default){ "use strict"; }; true threw exception SyntaxError: Unexpected token default.
-PASS (function(){"use strict";function g(default){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token default.
-PASS "use strict";/default/.test(function g(default){ "use strict"; }) threw exception SyntaxError: Unexpected token default.
-PASS (function(){"use strict";/default/.test(function g(default){ "use strict"; })}); true threw exception SyntaxError: Unexpected token default.
-PASS "use strict";try{}catch(default){}; true threw exception SyntaxError: Unexpected token default.
-PASS (function(){"use strict";try{}catch(default){}; true}); true threw exception SyntaxError: Unexpected token default.
-PASS "use strict";function default(){ "use strict"; }; true threw exception SyntaxError: Unexpected token default.
-PASS (function(){"use strict";function default(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token default.
-PASS "use strict";({ "default": 42 }.default === 42) is true
-PASS (function(){"use strict";({ "default": 42 }.default === 42)}); true is true
-PASS "use strict";({ default: 42 }.default === 42) is true
-PASS (function(){"use strict";({ default: 42 }.default === 42)}); true is true
-PASS "use strict";({ get default(){}, set default(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get default(){}, set default(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var delete; true threw exception SyntaxError: Unexpected token delete.
-PASS (function(){var delete; true}); true threw exception SyntaxError: Unexpected token delete.
-PASS var delete = 42; delete === 42 threw exception SyntaxError: Unexpected token delete.
-PASS (function(){var delete = 42; delete === 42}); true threw exception SyntaxError: Unexpected token delete.
-PASS function g(delete){  }; true threw exception SyntaxError: Unexpected token delete.
-PASS (function(){function g(delete){  }; true}); true threw exception SyntaxError: Unexpected token delete.
-PASS /delete/.test(function g(delete){  }) threw exception SyntaxError: Unexpected token delete.
-PASS (function(){/delete/.test(function g(delete){  })}); true threw exception SyntaxError: Unexpected token delete.
-PASS try{}catch(delete){}; true threw exception SyntaxError: Unexpected token delete.
-PASS (function(){try{}catch(delete){}; true}); true threw exception SyntaxError: Unexpected token delete.
-PASS function delete(){  }; true threw exception SyntaxError: Unexpected token delete.
-PASS (function(){function delete(){  }; true}); true threw exception SyntaxError: Unexpected token delete.
-PASS ({ "delete": 42 }.delete === 42) is true
-PASS (function(){({ "delete": 42 }.delete === 42)}); true is true
-PASS ({ delete: 42 }.delete === 42) is true
-PASS (function(){({ delete: 42 }.delete === 42)}); true is true
-PASS ({ get delete(){}, set delete(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get delete(){}, set delete(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var delete; true threw exception SyntaxError: Unexpected token delete.
-PASS (function(){"use strict";var delete; true}); true threw exception SyntaxError: Unexpected token delete.
-PASS "use strict";var delete = 42; delete === 42 threw exception SyntaxError: Unexpected token delete.
-PASS (function(){"use strict";var delete = 42; delete === 42}); true threw exception SyntaxError: Unexpected token delete.
-PASS "use strict";function g(delete){ "use strict"; }; true threw exception SyntaxError: Unexpected token delete.
-PASS (function(){"use strict";function g(delete){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token delete.
-PASS "use strict";/delete/.test(function g(delete){ "use strict"; }) threw exception SyntaxError: Unexpected token delete.
-PASS (function(){"use strict";/delete/.test(function g(delete){ "use strict"; })}); true threw exception SyntaxError: Unexpected token delete.
-PASS "use strict";try{}catch(delete){}; true threw exception SyntaxError: Unexpected token delete.
-PASS (function(){"use strict";try{}catch(delete){}; true}); true threw exception SyntaxError: Unexpected token delete.
-PASS "use strict";function delete(){ "use strict"; }; true threw exception SyntaxError: Unexpected token delete.
-PASS (function(){"use strict";function delete(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token delete.
-PASS "use strict";({ "delete": 42 }.delete === 42) is true
-PASS (function(){"use strict";({ "delete": 42 }.delete === 42)}); true is true
-PASS "use strict";({ delete: 42 }.delete === 42) is true
-PASS (function(){"use strict";({ delete: 42 }.delete === 42)}); true is true
-PASS "use strict";({ get delete(){}, set delete(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get delete(){}, set delete(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var do; true threw exception SyntaxError: Unexpected token do.
-PASS (function(){var do; true}); true threw exception SyntaxError: Unexpected token do.
-PASS var do = 42; do === 42 threw exception SyntaxError: Unexpected token do.
-PASS (function(){var do = 42; do === 42}); true threw exception SyntaxError: Unexpected token do.
-PASS function g(do){  }; true threw exception SyntaxError: Unexpected token do.
-PASS (function(){function g(do){  }; true}); true threw exception SyntaxError: Unexpected token do.
-PASS /do/.test(function g(do){  }) threw exception SyntaxError: Unexpected token do.
-PASS (function(){/do/.test(function g(do){  })}); true threw exception SyntaxError: Unexpected token do.
-PASS try{}catch(do){}; true threw exception SyntaxError: Unexpected token do.
-PASS (function(){try{}catch(do){}; true}); true threw exception SyntaxError: Unexpected token do.
-PASS function do(){  }; true threw exception SyntaxError: Unexpected token do.
-PASS (function(){function do(){  }; true}); true threw exception SyntaxError: Unexpected token do.
-PASS ({ "do": 42 }.do === 42) is true
-PASS (function(){({ "do": 42 }.do === 42)}); true is true
-PASS ({ do: 42 }.do === 42) is true
-PASS (function(){({ do: 42 }.do === 42)}); true is true
-PASS ({ get do(){}, set do(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get do(){}, set do(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var do; true threw exception SyntaxError: Unexpected token do.
-PASS (function(){"use strict";var do; true}); true threw exception SyntaxError: Unexpected token do.
-PASS "use strict";var do = 42; do === 42 threw exception SyntaxError: Unexpected token do.
-PASS (function(){"use strict";var do = 42; do === 42}); true threw exception SyntaxError: Unexpected token do.
-PASS "use strict";function g(do){ "use strict"; }; true threw exception SyntaxError: Unexpected token do.
-PASS (function(){"use strict";function g(do){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token do.
-PASS "use strict";/do/.test(function g(do){ "use strict"; }) threw exception SyntaxError: Unexpected token do.
-PASS (function(){"use strict";/do/.test(function g(do){ "use strict"; })}); true threw exception SyntaxError: Unexpected token do.
-PASS "use strict";try{}catch(do){}; true threw exception SyntaxError: Unexpected token do.
-PASS (function(){"use strict";try{}catch(do){}; true}); true threw exception SyntaxError: Unexpected token do.
-PASS "use strict";function do(){ "use strict"; }; true threw exception SyntaxError: Unexpected token do.
-PASS (function(){"use strict";function do(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token do.
-PASS "use strict";({ "do": 42 }.do === 42) is true
-PASS (function(){"use strict";({ "do": 42 }.do === 42)}); true is true
-PASS "use strict";({ do: 42 }.do === 42) is true
-PASS (function(){"use strict";({ do: 42 }.do === 42)}); true is true
-PASS "use strict";({ get do(){}, set do(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get do(){}, set do(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var else; true threw exception SyntaxError: Unexpected token else.
-PASS (function(){var else; true}); true threw exception SyntaxError: Unexpected token else.
-PASS var else = 42; else === 42 threw exception SyntaxError: Unexpected token else.
-PASS (function(){var else = 42; else === 42}); true threw exception SyntaxError: Unexpected token else.
-PASS function g(else){  }; true threw exception SyntaxError: Unexpected token else.
-PASS (function(){function g(else){  }; true}); true threw exception SyntaxError: Unexpected token else.
-PASS /else/.test(function g(else){  }) threw exception SyntaxError: Unexpected token else.
-PASS (function(){/else/.test(function g(else){  })}); true threw exception SyntaxError: Unexpected token else.
-PASS try{}catch(else){}; true threw exception SyntaxError: Unexpected token else.
-PASS (function(){try{}catch(else){}; true}); true threw exception SyntaxError: Unexpected token else.
-PASS function else(){  }; true threw exception SyntaxError: Unexpected token else.
-PASS (function(){function else(){  }; true}); true threw exception SyntaxError: Unexpected token else.
-PASS ({ "else": 42 }.else === 42) is true
-PASS (function(){({ "else": 42 }.else === 42)}); true is true
-PASS ({ else: 42 }.else === 42) is true
-PASS (function(){({ else: 42 }.else === 42)}); true is true
-PASS ({ get else(){}, set else(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get else(){}, set else(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var else; true threw exception SyntaxError: Unexpected token else.
-PASS (function(){"use strict";var else; true}); true threw exception SyntaxError: Unexpected token else.
-PASS "use strict";var else = 42; else === 42 threw exception SyntaxError: Unexpected token else.
-PASS (function(){"use strict";var else = 42; else === 42}); true threw exception SyntaxError: Unexpected token else.
-PASS "use strict";function g(else){ "use strict"; }; true threw exception SyntaxError: Unexpected token else.
-PASS (function(){"use strict";function g(else){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token else.
-PASS "use strict";/else/.test(function g(else){ "use strict"; }) threw exception SyntaxError: Unexpected token else.
-PASS (function(){"use strict";/else/.test(function g(else){ "use strict"; })}); true threw exception SyntaxError: Unexpected token else.
-PASS "use strict";try{}catch(else){}; true threw exception SyntaxError: Unexpected token else.
-PASS (function(){"use strict";try{}catch(else){}; true}); true threw exception SyntaxError: Unexpected token else.
-PASS "use strict";function else(){ "use strict"; }; true threw exception SyntaxError: Unexpected token else.
-PASS (function(){"use strict";function else(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token else.
-PASS "use strict";({ "else": 42 }.else === 42) is true
-PASS (function(){"use strict";({ "else": 42 }.else === 42)}); true is true
-PASS "use strict";({ else: 42 }.else === 42) is true
-PASS (function(){"use strict";({ else: 42 }.else === 42)}); true is true
-PASS "use strict";({ get else(){}, set else(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get else(){}, set else(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var finally; true threw exception SyntaxError: Unexpected token finally.
-PASS (function(){var finally; true}); true threw exception SyntaxError: Unexpected token finally.
-PASS var finally = 42; finally === 42 threw exception SyntaxError: Unexpected token finally.
-PASS (function(){var finally = 42; finally === 42}); true threw exception SyntaxError: Unexpected token finally.
-PASS function g(finally){  }; true threw exception SyntaxError: Unexpected token finally.
-PASS (function(){function g(finally){  }; true}); true threw exception SyntaxError: Unexpected token finally.
-PASS /finally/.test(function g(finally){  }) threw exception SyntaxError: Unexpected token finally.
-PASS (function(){/finally/.test(function g(finally){  })}); true threw exception SyntaxError: Unexpected token finally.
-PASS try{}catch(finally){}; true threw exception SyntaxError: Unexpected token finally.
-PASS (function(){try{}catch(finally){}; true}); true threw exception SyntaxError: Unexpected token finally.
-PASS function finally(){  }; true threw exception SyntaxError: Unexpected token finally.
-PASS (function(){function finally(){  }; true}); true threw exception SyntaxError: Unexpected token finally.
-PASS ({ "finally": 42 }.finally === 42) is true
-PASS (function(){({ "finally": 42 }.finally === 42)}); true is true
-PASS ({ finally: 42 }.finally === 42) is true
-PASS (function(){({ finally: 42 }.finally === 42)}); true is true
-PASS ({ get finally(){}, set finally(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get finally(){}, set finally(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var finally; true threw exception SyntaxError: Unexpected token finally.
-PASS (function(){"use strict";var finally; true}); true threw exception SyntaxError: Unexpected token finally.
-PASS "use strict";var finally = 42; finally === 42 threw exception SyntaxError: Unexpected token finally.
-PASS (function(){"use strict";var finally = 42; finally === 42}); true threw exception SyntaxError: Unexpected token finally.
-PASS "use strict";function g(finally){ "use strict"; }; true threw exception SyntaxError: Unexpected token finally.
-PASS (function(){"use strict";function g(finally){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token finally.
-PASS "use strict";/finally/.test(function g(finally){ "use strict"; }) threw exception SyntaxError: Unexpected token finally.
-PASS (function(){"use strict";/finally/.test(function g(finally){ "use strict"; })}); true threw exception SyntaxError: Unexpected token finally.
-PASS "use strict";try{}catch(finally){}; true threw exception SyntaxError: Unexpected token finally.
-PASS (function(){"use strict";try{}catch(finally){}; true}); true threw exception SyntaxError: Unexpected token finally.
-PASS "use strict";function finally(){ "use strict"; }; true threw exception SyntaxError: Unexpected token finally.
-PASS (function(){"use strict";function finally(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token finally.
-PASS "use strict";({ "finally": 42 }.finally === 42) is true
-PASS (function(){"use strict";({ "finally": 42 }.finally === 42)}); true is true
-PASS "use strict";({ finally: 42 }.finally === 42) is true
-PASS (function(){"use strict";({ finally: 42 }.finally === 42)}); true is true
-PASS "use strict";({ get finally(){}, set finally(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get finally(){}, set finally(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var for; true threw exception SyntaxError: Unexpected token for.
-PASS (function(){var for; true}); true threw exception SyntaxError: Unexpected token for.
-PASS var for = 42; for === 42 threw exception SyntaxError: Unexpected token for.
-PASS (function(){var for = 42; for === 42}); true threw exception SyntaxError: Unexpected token for.
-PASS function g(for){  }; true threw exception SyntaxError: Unexpected token for.
-PASS (function(){function g(for){  }; true}); true threw exception SyntaxError: Unexpected token for.
-PASS /for/.test(function g(for){  }) threw exception SyntaxError: Unexpected token for.
-PASS (function(){/for/.test(function g(for){  })}); true threw exception SyntaxError: Unexpected token for.
-PASS try{}catch(for){}; true threw exception SyntaxError: Unexpected token for.
-PASS (function(){try{}catch(for){}; true}); true threw exception SyntaxError: Unexpected token for.
-PASS function for(){  }; true threw exception SyntaxError: Unexpected token for.
-PASS (function(){function for(){  }; true}); true threw exception SyntaxError: Unexpected token for.
-PASS ({ "for": 42 }.for === 42) is true
-PASS (function(){({ "for": 42 }.for === 42)}); true is true
-PASS ({ for: 42 }.for === 42) is true
-PASS (function(){({ for: 42 }.for === 42)}); true is true
-PASS ({ get for(){}, set for(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get for(){}, set for(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var for; true threw exception SyntaxError: Unexpected token for.
-PASS (function(){"use strict";var for; true}); true threw exception SyntaxError: Unexpected token for.
-PASS "use strict";var for = 42; for === 42 threw exception SyntaxError: Unexpected token for.
-PASS (function(){"use strict";var for = 42; for === 42}); true threw exception SyntaxError: Unexpected token for.
-PASS "use strict";function g(for){ "use strict"; }; true threw exception SyntaxError: Unexpected token for.
-PASS (function(){"use strict";function g(for){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token for.
-PASS "use strict";/for/.test(function g(for){ "use strict"; }) threw exception SyntaxError: Unexpected token for.
-PASS (function(){"use strict";/for/.test(function g(for){ "use strict"; })}); true threw exception SyntaxError: Unexpected token for.
-PASS "use strict";try{}catch(for){}; true threw exception SyntaxError: Unexpected token for.
-PASS (function(){"use strict";try{}catch(for){}; true}); true threw exception SyntaxError: Unexpected token for.
-PASS "use strict";function for(){ "use strict"; }; true threw exception SyntaxError: Unexpected token for.
-PASS (function(){"use strict";function for(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token for.
-PASS "use strict";({ "for": 42 }.for === 42) is true
-PASS (function(){"use strict";({ "for": 42 }.for === 42)}); true is true
-PASS "use strict";({ for: 42 }.for === 42) is true
-PASS (function(){"use strict";({ for: 42 }.for === 42)}); true is true
-PASS "use strict";({ get for(){}, set for(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get for(){}, set for(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var function; true threw exception SyntaxError: Unexpected token function.
-PASS (function(){var function; true}); true threw exception SyntaxError: Unexpected token function.
-PASS var function = 42; function === 42 threw exception SyntaxError: Unexpected token function.
-PASS (function(){var function = 42; function === 42}); true threw exception SyntaxError: Unexpected token function.
-PASS function g(function){  }; true threw exception SyntaxError: Unexpected token function.
-PASS (function(){function g(function){  }; true}); true threw exception SyntaxError: Unexpected token function.
-PASS /function/.test(function g(function){  }) threw exception SyntaxError: Unexpected token function.
-PASS (function(){/function/.test(function g(function){  })}); true threw exception SyntaxError: Unexpected token function.
-PASS try{}catch(function){}; true threw exception SyntaxError: Unexpected token function.
-PASS (function(){try{}catch(function){}; true}); true threw exception SyntaxError: Unexpected token function.
-PASS function function(){  }; true threw exception SyntaxError: Unexpected token function.
-PASS (function(){function function(){  }; true}); true threw exception SyntaxError: Unexpected token function.
-PASS ({ "function": 42 }.function === 42) is true
-PASS (function(){({ "function": 42 }.function === 42)}); true is true
-PASS ({ function: 42 }.function === 42) is true
-PASS (function(){({ function: 42 }.function === 42)}); true is true
-PASS ({ get function(){}, set function(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get function(){}, set function(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var function; true threw exception SyntaxError: Unexpected token function.
-PASS (function(){"use strict";var function; true}); true threw exception SyntaxError: Unexpected token function.
-PASS "use strict";var function = 42; function === 42 threw exception SyntaxError: Unexpected token function.
-PASS (function(){"use strict";var function = 42; function === 42}); true threw exception SyntaxError: Unexpected token function.
-PASS "use strict";function g(function){ "use strict"; }; true threw exception SyntaxError: Unexpected token function.
-PASS (function(){"use strict";function g(function){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token function.
-PASS "use strict";/function/.test(function g(function){ "use strict"; }) threw exception SyntaxError: Unexpected token function.
-PASS (function(){"use strict";/function/.test(function g(function){ "use strict"; })}); true threw exception SyntaxError: Unexpected token function.
-PASS "use strict";try{}catch(function){}; true threw exception SyntaxError: Unexpected token function.
-PASS (function(){"use strict";try{}catch(function){}; true}); true threw exception SyntaxError: Unexpected token function.
-PASS "use strict";function function(){ "use strict"; }; true threw exception SyntaxError: Unexpected token function.
-PASS (function(){"use strict";function function(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token function.
-PASS "use strict";({ "function": 42 }.function === 42) is true
-PASS (function(){"use strict";({ "function": 42 }.function === 42)}); true is true
-PASS "use strict";({ function: 42 }.function === 42) is true
-PASS (function(){"use strict";({ function: 42 }.function === 42)}); true is true
-PASS "use strict";({ get function(){}, set function(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get function(){}, set function(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var if; true threw exception SyntaxError: Unexpected token if.
-PASS (function(){var if; true}); true threw exception SyntaxError: Unexpected token if.
-PASS var if = 42; if === 42 threw exception SyntaxError: Unexpected token if.
-PASS (function(){var if = 42; if === 42}); true threw exception SyntaxError: Unexpected token if.
-PASS function g(if){  }; true threw exception SyntaxError: Unexpected token if.
-PASS (function(){function g(if){  }; true}); true threw exception SyntaxError: Unexpected token if.
-PASS /if/.test(function g(if){  }) threw exception SyntaxError: Unexpected token if.
-PASS (function(){/if/.test(function g(if){  })}); true threw exception SyntaxError: Unexpected token if.
-PASS try{}catch(if){}; true threw exception SyntaxError: Unexpected token if.
-PASS (function(){try{}catch(if){}; true}); true threw exception SyntaxError: Unexpected token if.
-PASS function if(){  }; true threw exception SyntaxError: Unexpected token if.
-PASS (function(){function if(){  }; true}); true threw exception SyntaxError: Unexpected token if.
-PASS ({ "if": 42 }.if === 42) is true
-PASS (function(){({ "if": 42 }.if === 42)}); true is true
-PASS ({ if: 42 }.if === 42) is true
-PASS (function(){({ if: 42 }.if === 42)}); true is true
-PASS ({ get if(){}, set if(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get if(){}, set if(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var if; true threw exception SyntaxError: Unexpected token if.
-PASS (function(){"use strict";var if; true}); true threw exception SyntaxError: Unexpected token if.
-PASS "use strict";var if = 42; if === 42 threw exception SyntaxError: Unexpected token if.
-PASS (function(){"use strict";var if = 42; if === 42}); true threw exception SyntaxError: Unexpected token if.
-PASS "use strict";function g(if){ "use strict"; }; true threw exception SyntaxError: Unexpected token if.
-PASS (function(){"use strict";function g(if){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token if.
-PASS "use strict";/if/.test(function g(if){ "use strict"; }) threw exception SyntaxError: Unexpected token if.
-PASS (function(){"use strict";/if/.test(function g(if){ "use strict"; })}); true threw exception SyntaxError: Unexpected token if.
-PASS "use strict";try{}catch(if){}; true threw exception SyntaxError: Unexpected token if.
-PASS (function(){"use strict";try{}catch(if){}; true}); true threw exception SyntaxError: Unexpected token if.
-PASS "use strict";function if(){ "use strict"; }; true threw exception SyntaxError: Unexpected token if.
-PASS (function(){"use strict";function if(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token if.
-PASS "use strict";({ "if": 42 }.if === 42) is true
-PASS (function(){"use strict";({ "if": 42 }.if === 42)}); true is true
-PASS "use strict";({ if: 42 }.if === 42) is true
-PASS (function(){"use strict";({ if: 42 }.if === 42)}); true is true
-PASS "use strict";({ get if(){}, set if(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get if(){}, set if(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var in; true threw exception SyntaxError: Unexpected token in.
-PASS (function(){var in; true}); true threw exception SyntaxError: Unexpected token in.
-PASS var in = 42; in === 42 threw exception SyntaxError: Unexpected token in.
-PASS (function(){var in = 42; in === 42}); true threw exception SyntaxError: Unexpected token in.
-PASS function g(in){  }; true threw exception SyntaxError: Unexpected token in.
-PASS (function(){function g(in){  }; true}); true threw exception SyntaxError: Unexpected token in.
-PASS /in/.test(function g(in){  }) threw exception SyntaxError: Unexpected token in.
-PASS (function(){/in/.test(function g(in){  })}); true threw exception SyntaxError: Unexpected token in.
-PASS try{}catch(in){}; true threw exception SyntaxError: Unexpected token in.
-PASS (function(){try{}catch(in){}; true}); true threw exception SyntaxError: Unexpected token in.
-PASS function in(){  }; true threw exception SyntaxError: Unexpected token in.
-PASS (function(){function in(){  }; true}); true threw exception SyntaxError: Unexpected token in.
-PASS ({ "in": 42 }.in === 42) is true
-PASS (function(){({ "in": 42 }.in === 42)}); true is true
-PASS ({ in: 42 }.in === 42) is true
-PASS (function(){({ in: 42 }.in === 42)}); true is true
-PASS ({ get in(){}, set in(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get in(){}, set in(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var in; true threw exception SyntaxError: Unexpected token in.
-PASS (function(){"use strict";var in; true}); true threw exception SyntaxError: Unexpected token in.
-PASS "use strict";var in = 42; in === 42 threw exception SyntaxError: Unexpected token in.
-PASS (function(){"use strict";var in = 42; in === 42}); true threw exception SyntaxError: Unexpected token in.
-PASS "use strict";function g(in){ "use strict"; }; true threw exception SyntaxError: Unexpected token in.
-PASS (function(){"use strict";function g(in){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token in.
-PASS "use strict";/in/.test(function g(in){ "use strict"; }) threw exception SyntaxError: Unexpected token in.
-PASS (function(){"use strict";/in/.test(function g(in){ "use strict"; })}); true threw exception SyntaxError: Unexpected token in.
-PASS "use strict";try{}catch(in){}; true threw exception SyntaxError: Unexpected token in.
-PASS (function(){"use strict";try{}catch(in){}; true}); true threw exception SyntaxError: Unexpected token in.
-PASS "use strict";function in(){ "use strict"; }; true threw exception SyntaxError: Unexpected token in.
-PASS (function(){"use strict";function in(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token in.
-PASS "use strict";({ "in": 42 }.in === 42) is true
-PASS (function(){"use strict";({ "in": 42 }.in === 42)}); true is true
-PASS "use strict";({ in: 42 }.in === 42) is true
-PASS (function(){"use strict";({ in: 42 }.in === 42)}); true is true
-PASS "use strict";({ get in(){}, set in(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get in(){}, set in(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var instanceof; true threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){var instanceof; true}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS var instanceof = 42; instanceof === 42 threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){var instanceof = 42; instanceof === 42}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS function g(instanceof){  }; true threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){function g(instanceof){  }; true}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS /instanceof/.test(function g(instanceof){  }) threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){/instanceof/.test(function g(instanceof){  })}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS try{}catch(instanceof){}; true threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){try{}catch(instanceof){}; true}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS function instanceof(){  }; true threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){function instanceof(){  }; true}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS ({ "instanceof": 42 }.instanceof === 42) is true
-PASS (function(){({ "instanceof": 42 }.instanceof === 42)}); true is true
-PASS ({ instanceof: 42 }.instanceof === 42) is true
-PASS (function(){({ instanceof: 42 }.instanceof === 42)}); true is true
-PASS ({ get instanceof(){}, set instanceof(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get instanceof(){}, set instanceof(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var instanceof; true threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){"use strict";var instanceof; true}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS "use strict";var instanceof = 42; instanceof === 42 threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){"use strict";var instanceof = 42; instanceof === 42}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS "use strict";function g(instanceof){ "use strict"; }; true threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){"use strict";function g(instanceof){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS "use strict";/instanceof/.test(function g(instanceof){ "use strict"; }) threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){"use strict";/instanceof/.test(function g(instanceof){ "use strict"; })}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS "use strict";try{}catch(instanceof){}; true threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){"use strict";try{}catch(instanceof){}; true}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS "use strict";function instanceof(){ "use strict"; }; true threw exception SyntaxError: Unexpected token instanceof.
-PASS (function(){"use strict";function instanceof(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token instanceof.
-PASS "use strict";({ "instanceof": 42 }.instanceof === 42) is true
-PASS (function(){"use strict";({ "instanceof": 42 }.instanceof === 42)}); true is true
-PASS "use strict";({ instanceof: 42 }.instanceof === 42) is true
-PASS (function(){"use strict";({ instanceof: 42 }.instanceof === 42)}); true is true
-PASS "use strict";({ get instanceof(){}, set instanceof(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get instanceof(){}, set instanceof(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var new; true threw exception SyntaxError: Unexpected token new.
-PASS (function(){var new; true}); true threw exception SyntaxError: Unexpected token new.
-PASS var new = 42; new === 42 threw exception SyntaxError: Unexpected token new.
-PASS (function(){var new = 42; new === 42}); true threw exception SyntaxError: Unexpected token new.
-PASS function g(new){  }; true threw exception SyntaxError: Unexpected token new.
-PASS (function(){function g(new){  }; true}); true threw exception SyntaxError: Unexpected token new.
-PASS /new/.test(function g(new){  }) threw exception SyntaxError: Unexpected token new.
-PASS (function(){/new/.test(function g(new){  })}); true threw exception SyntaxError: Unexpected token new.
-PASS try{}catch(new){}; true threw exception SyntaxError: Unexpected token new.
-PASS (function(){try{}catch(new){}; true}); true threw exception SyntaxError: Unexpected token new.
-PASS function new(){  }; true threw exception SyntaxError: Unexpected token new.
-PASS (function(){function new(){  }; true}); true threw exception SyntaxError: Unexpected token new.
-PASS ({ "new": 42 }.new === 42) is true
-PASS (function(){({ "new": 42 }.new === 42)}); true is true
-PASS ({ new: 42 }.new === 42) is true
-PASS (function(){({ new: 42 }.new === 42)}); true is true
-PASS ({ get new(){}, set new(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get new(){}, set new(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var new; true threw exception SyntaxError: Unexpected token new.
-PASS (function(){"use strict";var new; true}); true threw exception SyntaxError: Unexpected token new.
-PASS "use strict";var new = 42; new === 42 threw exception SyntaxError: Unexpected token new.
-PASS (function(){"use strict";var new = 42; new === 42}); true threw exception SyntaxError: Unexpected token new.
-PASS "use strict";function g(new){ "use strict"; }; true threw exception SyntaxError: Unexpected token new.
-PASS (function(){"use strict";function g(new){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token new.
-PASS "use strict";/new/.test(function g(new){ "use strict"; }) threw exception SyntaxError: Unexpected token new.
-PASS (function(){"use strict";/new/.test(function g(new){ "use strict"; })}); true threw exception SyntaxError: Unexpected token new.
-PASS "use strict";try{}catch(new){}; true threw exception SyntaxError: Unexpected token new.
-PASS (function(){"use strict";try{}catch(new){}; true}); true threw exception SyntaxError: Unexpected token new.
-PASS "use strict";function new(){ "use strict"; }; true threw exception SyntaxError: Unexpected token new.
-PASS (function(){"use strict";function new(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token new.
-PASS "use strict";({ "new": 42 }.new === 42) is true
-PASS (function(){"use strict";({ "new": 42 }.new === 42)}); true is true
-PASS "use strict";({ new: 42 }.new === 42) is true
-PASS (function(){"use strict";({ new: 42 }.new === 42)}); true is true
-PASS "use strict";({ get new(){}, set new(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get new(){}, set new(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var return; true threw exception SyntaxError: Unexpected token return.
-PASS (function(){var return; true}); true threw exception SyntaxError: Unexpected token return.
-PASS var return = 42; return === 42 threw exception SyntaxError: Unexpected token return.
-PASS (function(){var return = 42; return === 42}); true threw exception SyntaxError: Unexpected token return.
-PASS function g(return){  }; true threw exception SyntaxError: Unexpected token return.
-PASS (function(){function g(return){  }; true}); true threw exception SyntaxError: Unexpected token return.
-PASS /return/.test(function g(return){  }) threw exception SyntaxError: Unexpected token return.
-PASS (function(){/return/.test(function g(return){  })}); true threw exception SyntaxError: Unexpected token return.
-PASS try{}catch(return){}; true threw exception SyntaxError: Unexpected token return.
-PASS (function(){try{}catch(return){}; true}); true threw exception SyntaxError: Unexpected token return.
-PASS function return(){  }; true threw exception SyntaxError: Unexpected token return.
-PASS (function(){function return(){  }; true}); true threw exception SyntaxError: Unexpected token return.
-PASS ({ "return": 42 }.return === 42) is true
-PASS (function(){({ "return": 42 }.return === 42)}); true is true
-PASS ({ return: 42 }.return === 42) is true
-PASS (function(){({ return: 42 }.return === 42)}); true is true
-PASS ({ get return(){}, set return(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get return(){}, set return(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var return; true threw exception SyntaxError: Unexpected token return.
-PASS (function(){"use strict";var return; true}); true threw exception SyntaxError: Unexpected token return.
-PASS "use strict";var return = 42; return === 42 threw exception SyntaxError: Unexpected token return.
-PASS (function(){"use strict";var return = 42; return === 42}); true threw exception SyntaxError: Unexpected token return.
-PASS "use strict";function g(return){ "use strict"; }; true threw exception SyntaxError: Unexpected token return.
-PASS (function(){"use strict";function g(return){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token return.
-PASS "use strict";/return/.test(function g(return){ "use strict"; }) threw exception SyntaxError: Unexpected token return.
-PASS (function(){"use strict";/return/.test(function g(return){ "use strict"; })}); true threw exception SyntaxError: Unexpected token return.
-PASS "use strict";try{}catch(return){}; true threw exception SyntaxError: Unexpected token return.
-PASS (function(){"use strict";try{}catch(return){}; true}); true threw exception SyntaxError: Unexpected token return.
-PASS "use strict";function return(){ "use strict"; }; true threw exception SyntaxError: Unexpected token return.
-PASS (function(){"use strict";function return(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token return.
-PASS "use strict";({ "return": 42 }.return === 42) is true
-PASS (function(){"use strict";({ "return": 42 }.return === 42)}); true is true
-PASS "use strict";({ return: 42 }.return === 42) is true
-PASS (function(){"use strict";({ return: 42 }.return === 42)}); true is true
-PASS "use strict";({ get return(){}, set return(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get return(){}, set return(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var switch; true threw exception SyntaxError: Unexpected token switch.
-PASS (function(){var switch; true}); true threw exception SyntaxError: Unexpected token switch.
-PASS var switch = 42; switch === 42 threw exception SyntaxError: Unexpected token switch.
-PASS (function(){var switch = 42; switch === 42}); true threw exception SyntaxError: Unexpected token switch.
-PASS function g(switch){  }; true threw exception SyntaxError: Unexpected token switch.
-PASS (function(){function g(switch){  }; true}); true threw exception SyntaxError: Unexpected token switch.
-PASS /switch/.test(function g(switch){  }) threw exception SyntaxError: Unexpected token switch.
-PASS (function(){/switch/.test(function g(switch){  })}); true threw exception SyntaxError: Unexpected token switch.
-PASS try{}catch(switch){}; true threw exception SyntaxError: Unexpected token switch.
-PASS (function(){try{}catch(switch){}; true}); true threw exception SyntaxError: Unexpected token switch.
-PASS function switch(){  }; true threw exception SyntaxError: Unexpected token switch.
-PASS (function(){function switch(){  }; true}); true threw exception SyntaxError: Unexpected token switch.
-PASS ({ "switch": 42 }.switch === 42) is true
-PASS (function(){({ "switch": 42 }.switch === 42)}); true is true
-PASS ({ switch: 42 }.switch === 42) is true
-PASS (function(){({ switch: 42 }.switch === 42)}); true is true
-PASS ({ get switch(){}, set switch(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get switch(){}, set switch(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var switch; true threw exception SyntaxError: Unexpected token switch.
-PASS (function(){"use strict";var switch; true}); true threw exception SyntaxError: Unexpected token switch.
-PASS "use strict";var switch = 42; switch === 42 threw exception SyntaxError: Unexpected token switch.
-PASS (function(){"use strict";var switch = 42; switch === 42}); true threw exception SyntaxError: Unexpected token switch.
-PASS "use strict";function g(switch){ "use strict"; }; true threw exception SyntaxError: Unexpected token switch.
-PASS (function(){"use strict";function g(switch){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token switch.
-PASS "use strict";/switch/.test(function g(switch){ "use strict"; }) threw exception SyntaxError: Unexpected token switch.
-PASS (function(){"use strict";/switch/.test(function g(switch){ "use strict"; })}); true threw exception SyntaxError: Unexpected token switch.
-PASS "use strict";try{}catch(switch){}; true threw exception SyntaxError: Unexpected token switch.
-PASS (function(){"use strict";try{}catch(switch){}; true}); true threw exception SyntaxError: Unexpected token switch.
-PASS "use strict";function switch(){ "use strict"; }; true threw exception SyntaxError: Unexpected token switch.
-PASS (function(){"use strict";function switch(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token switch.
-PASS "use strict";({ "switch": 42 }.switch === 42) is true
-PASS (function(){"use strict";({ "switch": 42 }.switch === 42)}); true is true
-PASS "use strict";({ switch: 42 }.switch === 42) is true
-PASS (function(){"use strict";({ switch: 42 }.switch === 42)}); true is true
-PASS "use strict";({ get switch(){}, set switch(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get switch(){}, set switch(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var this; true threw exception SyntaxError: Unexpected token this.
-PASS (function(){var this; true}); true threw exception SyntaxError: Unexpected token this.
-PASS var this = 42; this === 42 threw exception SyntaxError: Unexpected token this.
-PASS (function(){var this = 42; this === 42}); true threw exception SyntaxError: Unexpected token this.
-PASS function g(this){  }; true threw exception SyntaxError: Unexpected token this.
-PASS (function(){function g(this){  }; true}); true threw exception SyntaxError: Unexpected token this.
-PASS /this/.test(function g(this){  }) threw exception SyntaxError: Unexpected token this.
-PASS (function(){/this/.test(function g(this){  })}); true threw exception SyntaxError: Unexpected token this.
-PASS try{}catch(this){}; true threw exception SyntaxError: Unexpected token this.
-PASS (function(){try{}catch(this){}; true}); true threw exception SyntaxError: Unexpected token this.
-PASS function this(){  }; true threw exception SyntaxError: Unexpected token this.
-PASS (function(){function this(){  }; true}); true threw exception SyntaxError: Unexpected token this.
-PASS ({ "this": 42 }.this === 42) is true
-PASS (function(){({ "this": 42 }.this === 42)}); true is true
-PASS ({ this: 42 }.this === 42) is true
-PASS (function(){({ this: 42 }.this === 42)}); true is true
-PASS ({ get this(){}, set this(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get this(){}, set this(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var this; true threw exception SyntaxError: Unexpected token this.
-PASS (function(){"use strict";var this; true}); true threw exception SyntaxError: Unexpected token this.
-PASS "use strict";var this = 42; this === 42 threw exception SyntaxError: Unexpected token this.
-PASS (function(){"use strict";var this = 42; this === 42}); true threw exception SyntaxError: Unexpected token this.
-PASS "use strict";function g(this){ "use strict"; }; true threw exception SyntaxError: Unexpected token this.
-PASS (function(){"use strict";function g(this){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token this.
-PASS "use strict";/this/.test(function g(this){ "use strict"; }) threw exception SyntaxError: Unexpected token this.
-PASS (function(){"use strict";/this/.test(function g(this){ "use strict"; })}); true threw exception SyntaxError: Unexpected token this.
-PASS "use strict";try{}catch(this){}; true threw exception SyntaxError: Unexpected token this.
-PASS (function(){"use strict";try{}catch(this){}; true}); true threw exception SyntaxError: Unexpected token this.
-PASS "use strict";function this(){ "use strict"; }; true threw exception SyntaxError: Unexpected token this.
-PASS (function(){"use strict";function this(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token this.
-PASS "use strict";({ "this": 42 }.this === 42) is true
-PASS (function(){"use strict";({ "this": 42 }.this === 42)}); true is true
-PASS "use strict";({ this: 42 }.this === 42) is true
-PASS (function(){"use strict";({ this: 42 }.this === 42)}); true is true
-PASS "use strict";({ get this(){}, set this(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get this(){}, set this(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var throw; true threw exception SyntaxError: Unexpected token throw.
-PASS (function(){var throw; true}); true threw exception SyntaxError: Unexpected token throw.
-PASS var throw = 42; throw === 42 threw exception SyntaxError: Unexpected token throw.
-PASS (function(){var throw = 42; throw === 42}); true threw exception SyntaxError: Unexpected token throw.
-PASS function g(throw){  }; true threw exception SyntaxError: Unexpected token throw.
-PASS (function(){function g(throw){  }; true}); true threw exception SyntaxError: Unexpected token throw.
-PASS /throw/.test(function g(throw){  }) threw exception SyntaxError: Unexpected token throw.
-PASS (function(){/throw/.test(function g(throw){  })}); true threw exception SyntaxError: Unexpected token throw.
-PASS try{}catch(throw){}; true threw exception SyntaxError: Unexpected token throw.
-PASS (function(){try{}catch(throw){}; true}); true threw exception SyntaxError: Unexpected token throw.
-PASS function throw(){  }; true threw exception SyntaxError: Unexpected token throw.
-PASS (function(){function throw(){  }; true}); true threw exception SyntaxError: Unexpected token throw.
-PASS ({ "throw": 42 }.throw === 42) is true
-PASS (function(){({ "throw": 42 }.throw === 42)}); true is true
-PASS ({ throw: 42 }.throw === 42) is true
-PASS (function(){({ throw: 42 }.throw === 42)}); true is true
-PASS ({ get throw(){}, set throw(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get throw(){}, set throw(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var throw; true threw exception SyntaxError: Unexpected token throw.
-PASS (function(){"use strict";var throw; true}); true threw exception SyntaxError: Unexpected token throw.
-PASS "use strict";var throw = 42; throw === 42 threw exception SyntaxError: Unexpected token throw.
-PASS (function(){"use strict";var throw = 42; throw === 42}); true threw exception SyntaxError: Unexpected token throw.
-PASS "use strict";function g(throw){ "use strict"; }; true threw exception SyntaxError: Unexpected token throw.
-PASS (function(){"use strict";function g(throw){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token throw.
-PASS "use strict";/throw/.test(function g(throw){ "use strict"; }) threw exception SyntaxError: Unexpected token throw.
-PASS (function(){"use strict";/throw/.test(function g(throw){ "use strict"; })}); true threw exception SyntaxError: Unexpected token throw.
-PASS "use strict";try{}catch(throw){}; true threw exception SyntaxError: Unexpected token throw.
-PASS (function(){"use strict";try{}catch(throw){}; true}); true threw exception SyntaxError: Unexpected token throw.
-PASS "use strict";function throw(){ "use strict"; }; true threw exception SyntaxError: Unexpected token throw.
-PASS (function(){"use strict";function throw(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token throw.
-PASS "use strict";({ "throw": 42 }.throw === 42) is true
-PASS (function(){"use strict";({ "throw": 42 }.throw === 42)}); true is true
-PASS "use strict";({ throw: 42 }.throw === 42) is true
-PASS (function(){"use strict";({ throw: 42 }.throw === 42)}); true is true
-PASS "use strict";({ get throw(){}, set throw(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get throw(){}, set throw(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var try; true threw exception SyntaxError: Unexpected token try.
-PASS (function(){var try; true}); true threw exception SyntaxError: Unexpected token try.
-PASS var try = 42; try === 42 threw exception SyntaxError: Unexpected token try.
-PASS (function(){var try = 42; try === 42}); true threw exception SyntaxError: Unexpected token try.
-PASS function g(try){  }; true threw exception SyntaxError: Unexpected token try.
-PASS (function(){function g(try){  }; true}); true threw exception SyntaxError: Unexpected token try.
-PASS /try/.test(function g(try){  }) threw exception SyntaxError: Unexpected token try.
-PASS (function(){/try/.test(function g(try){  })}); true threw exception SyntaxError: Unexpected token try.
-PASS try{}catch(try){}; true threw exception SyntaxError: Unexpected token try.
-PASS (function(){try{}catch(try){}; true}); true threw exception SyntaxError: Unexpected token try.
-PASS function try(){  }; true threw exception SyntaxError: Unexpected token try.
-PASS (function(){function try(){  }; true}); true threw exception SyntaxError: Unexpected token try.
-PASS ({ "try": 42 }.try === 42) is true
-PASS (function(){({ "try": 42 }.try === 42)}); true is true
-PASS ({ try: 42 }.try === 42) is true
-PASS (function(){({ try: 42 }.try === 42)}); true is true
-PASS ({ get try(){}, set try(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get try(){}, set try(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var try; true threw exception SyntaxError: Unexpected token try.
-PASS (function(){"use strict";var try; true}); true threw exception SyntaxError: Unexpected token try.
-PASS "use strict";var try = 42; try === 42 threw exception SyntaxError: Unexpected token try.
-PASS (function(){"use strict";var try = 42; try === 42}); true threw exception SyntaxError: Unexpected token try.
-PASS "use strict";function g(try){ "use strict"; }; true threw exception SyntaxError: Unexpected token try.
-PASS (function(){"use strict";function g(try){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token try.
-PASS "use strict";/try/.test(function g(try){ "use strict"; }) threw exception SyntaxError: Unexpected token try.
-PASS (function(){"use strict";/try/.test(function g(try){ "use strict"; })}); true threw exception SyntaxError: Unexpected token try.
-PASS "use strict";try{}catch(try){}; true threw exception SyntaxError: Unexpected token try.
-PASS (function(){"use strict";try{}catch(try){}; true}); true threw exception SyntaxError: Unexpected token try.
-PASS "use strict";function try(){ "use strict"; }; true threw exception SyntaxError: Unexpected token try.
-PASS (function(){"use strict";function try(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token try.
-PASS "use strict";({ "try": 42 }.try === 42) is true
-PASS (function(){"use strict";({ "try": 42 }.try === 42)}); true is true
-PASS "use strict";({ try: 42 }.try === 42) is true
-PASS (function(){"use strict";({ try: 42 }.try === 42)}); true is true
-PASS "use strict";({ get try(){}, set try(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get try(){}, set try(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var typeof; true threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){var typeof; true}); true threw exception SyntaxError: Unexpected token typeof.
-PASS var typeof = 42; typeof === 42 threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){var typeof = 42; typeof === 42}); true threw exception SyntaxError: Unexpected token typeof.
-PASS function g(typeof){  }; true threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){function g(typeof){  }; true}); true threw exception SyntaxError: Unexpected token typeof.
-PASS /typeof/.test(function g(typeof){  }) threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){/typeof/.test(function g(typeof){  })}); true threw exception SyntaxError: Unexpected token typeof.
-PASS try{}catch(typeof){}; true threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){try{}catch(typeof){}; true}); true threw exception SyntaxError: Unexpected token typeof.
-PASS function typeof(){  }; true threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){function typeof(){  }; true}); true threw exception SyntaxError: Unexpected token typeof.
-PASS ({ "typeof": 42 }.typeof === 42) is true
-PASS (function(){({ "typeof": 42 }.typeof === 42)}); true is true
-PASS ({ typeof: 42 }.typeof === 42) is true
-PASS (function(){({ typeof: 42 }.typeof === 42)}); true is true
-PASS ({ get typeof(){}, set typeof(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get typeof(){}, set typeof(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var typeof; true threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){"use strict";var typeof; true}); true threw exception SyntaxError: Unexpected token typeof.
-PASS "use strict";var typeof = 42; typeof === 42 threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){"use strict";var typeof = 42; typeof === 42}); true threw exception SyntaxError: Unexpected token typeof.
-PASS "use strict";function g(typeof){ "use strict"; }; true threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){"use strict";function g(typeof){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token typeof.
-PASS "use strict";/typeof/.test(function g(typeof){ "use strict"; }) threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){"use strict";/typeof/.test(function g(typeof){ "use strict"; })}); true threw exception SyntaxError: Unexpected token typeof.
-PASS "use strict";try{}catch(typeof){}; true threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){"use strict";try{}catch(typeof){}; true}); true threw exception SyntaxError: Unexpected token typeof.
-PASS "use strict";function typeof(){ "use strict"; }; true threw exception SyntaxError: Unexpected token typeof.
-PASS (function(){"use strict";function typeof(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token typeof.
-PASS "use strict";({ "typeof": 42 }.typeof === 42) is true
-PASS (function(){"use strict";({ "typeof": 42 }.typeof === 42)}); true is true
-PASS "use strict";({ typeof: 42 }.typeof === 42) is true
-PASS (function(){"use strict";({ typeof: 42 }.typeof === 42)}); true is true
-PASS "use strict";({ get typeof(){}, set typeof(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get typeof(){}, set typeof(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var var; true threw exception SyntaxError: Unexpected token var.
-PASS (function(){var var; true}); true threw exception SyntaxError: Unexpected token var.
-PASS var var = 42; var === 42 threw exception SyntaxError: Unexpected token var.
-PASS (function(){var var = 42; var === 42}); true threw exception SyntaxError: Unexpected token var.
-PASS function g(var){  }; true threw exception SyntaxError: Unexpected token var.
-PASS (function(){function g(var){  }; true}); true threw exception SyntaxError: Unexpected token var.
-PASS /var/.test(function g(var){  }) threw exception SyntaxError: Unexpected token var.
-PASS (function(){/var/.test(function g(var){  })}); true threw exception SyntaxError: Unexpected token var.
-PASS try{}catch(var){}; true threw exception SyntaxError: Unexpected token var.
-PASS (function(){try{}catch(var){}; true}); true threw exception SyntaxError: Unexpected token var.
-PASS function var(){  }; true threw exception SyntaxError: Unexpected token var.
-PASS (function(){function var(){  }; true}); true threw exception SyntaxError: Unexpected token var.
-PASS ({ "var": 42 }.var === 42) is true
-PASS (function(){({ "var": 42 }.var === 42)}); true is true
-PASS ({ var: 42 }.var === 42) is true
-PASS (function(){({ var: 42 }.var === 42)}); true is true
-PASS ({ get var(){}, set var(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get var(){}, set var(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var var; true threw exception SyntaxError: Unexpected token var.
-PASS (function(){"use strict";var var; true}); true threw exception SyntaxError: Unexpected token var.
-PASS "use strict";var var = 42; var === 42 threw exception SyntaxError: Unexpected token var.
-PASS (function(){"use strict";var var = 42; var === 42}); true threw exception SyntaxError: Unexpected token var.
-PASS "use strict";function g(var){ "use strict"; }; true threw exception SyntaxError: Unexpected token var.
-PASS (function(){"use strict";function g(var){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token var.
-PASS "use strict";/var/.test(function g(var){ "use strict"; }) threw exception SyntaxError: Unexpected token var.
-PASS (function(){"use strict";/var/.test(function g(var){ "use strict"; })}); true threw exception SyntaxError: Unexpected token var.
-PASS "use strict";try{}catch(var){}; true threw exception SyntaxError: Unexpected token var.
-PASS (function(){"use strict";try{}catch(var){}; true}); true threw exception SyntaxError: Unexpected token var.
-PASS "use strict";function var(){ "use strict"; }; true threw exception SyntaxError: Unexpected token var.
-PASS (function(){"use strict";function var(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token var.
-PASS "use strict";({ "var": 42 }.var === 42) is true
-PASS (function(){"use strict";({ "var": 42 }.var === 42)}); true is true
-PASS "use strict";({ var: 42 }.var === 42) is true
-PASS (function(){"use strict";({ var: 42 }.var === 42)}); true is true
-PASS "use strict";({ get var(){}, set var(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get var(){}, set var(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var void; true threw exception SyntaxError: Unexpected token void.
-PASS (function(){var void; true}); true threw exception SyntaxError: Unexpected token void.
-PASS var void = 42; void === 42 threw exception SyntaxError: Unexpected token void.
-PASS (function(){var void = 42; void === 42}); true threw exception SyntaxError: Unexpected token void.
-PASS function g(void){  }; true threw exception SyntaxError: Unexpected token void.
-PASS (function(){function g(void){  }; true}); true threw exception SyntaxError: Unexpected token void.
-PASS /void/.test(function g(void){  }) threw exception SyntaxError: Unexpected token void.
-PASS (function(){/void/.test(function g(void){  })}); true threw exception SyntaxError: Unexpected token void.
-PASS try{}catch(void){}; true threw exception SyntaxError: Unexpected token void.
-PASS (function(){try{}catch(void){}; true}); true threw exception SyntaxError: Unexpected token void.
-PASS function void(){  }; true threw exception SyntaxError: Unexpected token void.
-PASS (function(){function void(){  }; true}); true threw exception SyntaxError: Unexpected token void.
-PASS ({ "void": 42 }.void === 42) is true
-PASS (function(){({ "void": 42 }.void === 42)}); true is true
-PASS ({ void: 42 }.void === 42) is true
-PASS (function(){({ void: 42 }.void === 42)}); true is true
-PASS ({ get void(){}, set void(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get void(){}, set void(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var void; true threw exception SyntaxError: Unexpected token void.
-PASS (function(){"use strict";var void; true}); true threw exception SyntaxError: Unexpected token void.
-PASS "use strict";var void = 42; void === 42 threw exception SyntaxError: Unexpected token void.
-PASS (function(){"use strict";var void = 42; void === 42}); true threw exception SyntaxError: Unexpected token void.
-PASS "use strict";function g(void){ "use strict"; }; true threw exception SyntaxError: Unexpected token void.
-PASS (function(){"use strict";function g(void){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token void.
-PASS "use strict";/void/.test(function g(void){ "use strict"; }) threw exception SyntaxError: Unexpected token void.
-PASS (function(){"use strict";/void/.test(function g(void){ "use strict"; })}); true threw exception SyntaxError: Unexpected token void.
-PASS "use strict";try{}catch(void){}; true threw exception SyntaxError: Unexpected token void.
-PASS (function(){"use strict";try{}catch(void){}; true}); true threw exception SyntaxError: Unexpected token void.
-PASS "use strict";function void(){ "use strict"; }; true threw exception SyntaxError: Unexpected token void.
-PASS (function(){"use strict";function void(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token void.
-PASS "use strict";({ "void": 42 }.void === 42) is true
-PASS (function(){"use strict";({ "void": 42 }.void === 42)}); true is true
-PASS "use strict";({ void: 42 }.void === 42) is true
-PASS (function(){"use strict";({ void: 42 }.void === 42)}); true is true
-PASS "use strict";({ get void(){}, set void(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get void(){}, set void(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var while; true threw exception SyntaxError: Unexpected token while.
-PASS (function(){var while; true}); true threw exception SyntaxError: Unexpected token while.
-PASS var while = 42; while === 42 threw exception SyntaxError: Unexpected token while.
-PASS (function(){var while = 42; while === 42}); true threw exception SyntaxError: Unexpected token while.
-PASS function g(while){  }; true threw exception SyntaxError: Unexpected token while.
-PASS (function(){function g(while){  }; true}); true threw exception SyntaxError: Unexpected token while.
-PASS /while/.test(function g(while){  }) threw exception SyntaxError: Unexpected token while.
-PASS (function(){/while/.test(function g(while){  })}); true threw exception SyntaxError: Unexpected token while.
-PASS try{}catch(while){}; true threw exception SyntaxError: Unexpected token while.
-PASS (function(){try{}catch(while){}; true}); true threw exception SyntaxError: Unexpected token while.
-PASS function while(){  }; true threw exception SyntaxError: Unexpected token while.
-PASS (function(){function while(){  }; true}); true threw exception SyntaxError: Unexpected token while.
-PASS ({ "while": 42 }.while === 42) is true
-PASS (function(){({ "while": 42 }.while === 42)}); true is true
-PASS ({ while: 42 }.while === 42) is true
-PASS (function(){({ while: 42 }.while === 42)}); true is true
-PASS ({ get while(){}, set while(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get while(){}, set while(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var while; true threw exception SyntaxError: Unexpected token while.
-PASS (function(){"use strict";var while; true}); true threw exception SyntaxError: Unexpected token while.
-PASS "use strict";var while = 42; while === 42 threw exception SyntaxError: Unexpected token while.
-PASS (function(){"use strict";var while = 42; while === 42}); true threw exception SyntaxError: Unexpected token while.
-PASS "use strict";function g(while){ "use strict"; }; true threw exception SyntaxError: Unexpected token while.
-PASS (function(){"use strict";function g(while){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token while.
-PASS "use strict";/while/.test(function g(while){ "use strict"; }) threw exception SyntaxError: Unexpected token while.
-PASS (function(){"use strict";/while/.test(function g(while){ "use strict"; })}); true threw exception SyntaxError: Unexpected token while.
-PASS "use strict";try{}catch(while){}; true threw exception SyntaxError: Unexpected token while.
-PASS (function(){"use strict";try{}catch(while){}; true}); true threw exception SyntaxError: Unexpected token while.
-PASS "use strict";function while(){ "use strict"; }; true threw exception SyntaxError: Unexpected token while.
-PASS (function(){"use strict";function while(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token while.
-PASS "use strict";({ "while": 42 }.while === 42) is true
-PASS (function(){"use strict";({ "while": 42 }.while === 42)}); true is true
-PASS "use strict";({ while: 42 }.while === 42) is true
-PASS (function(){"use strict";({ while: 42 }.while === 42)}); true is true
-PASS "use strict";({ get while(){}, set while(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get while(){}, set while(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var with; true threw exception SyntaxError: Unexpected token with.
-PASS (function(){var with; true}); true threw exception SyntaxError: Unexpected token with.
-PASS var with = 42; with === 42 threw exception SyntaxError: Unexpected token with.
-PASS (function(){var with = 42; with === 42}); true threw exception SyntaxError: Unexpected token with.
-PASS function g(with){  }; true threw exception SyntaxError: Unexpected token with.
-PASS (function(){function g(with){  }; true}); true threw exception SyntaxError: Unexpected token with.
-PASS /with/.test(function g(with){  }) threw exception SyntaxError: Unexpected token with.
-PASS (function(){/with/.test(function g(with){  })}); true threw exception SyntaxError: Unexpected token with.
-PASS try{}catch(with){}; true threw exception SyntaxError: Unexpected token with.
-PASS (function(){try{}catch(with){}; true}); true threw exception SyntaxError: Unexpected token with.
-PASS function with(){  }; true threw exception SyntaxError: Unexpected token with.
-PASS (function(){function with(){  }; true}); true threw exception SyntaxError: Unexpected token with.
-PASS ({ "with": 42 }.with === 42) is true
-PASS (function(){({ "with": 42 }.with === 42)}); true is true
-PASS ({ with: 42 }.with === 42) is true
-PASS (function(){({ with: 42 }.with === 42)}); true is true
-PASS ({ get with(){}, set with(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get with(){}, set with(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var with; true threw exception SyntaxError: Unexpected token with.
-PASS (function(){"use strict";var with; true}); true threw exception SyntaxError: Unexpected token with.
-PASS "use strict";var with = 42; with === 42 threw exception SyntaxError: Unexpected token with.
-PASS (function(){"use strict";var with = 42; with === 42}); true threw exception SyntaxError: Unexpected token with.
-PASS "use strict";function g(with){ "use strict"; }; true threw exception SyntaxError: Unexpected token with.
-PASS (function(){"use strict";function g(with){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token with.
-PASS "use strict";/with/.test(function g(with){ "use strict"; }) threw exception SyntaxError: Unexpected token with.
-PASS (function(){"use strict";/with/.test(function g(with){ "use strict"; })}); true threw exception SyntaxError: Unexpected token with.
-PASS "use strict";try{}catch(with){}; true threw exception SyntaxError: Unexpected token with.
-PASS (function(){"use strict";try{}catch(with){}; true}); true threw exception SyntaxError: Unexpected token with.
-PASS "use strict";function with(){ "use strict"; }; true threw exception SyntaxError: Unexpected token with.
-PASS (function(){"use strict";function with(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token with.
-PASS "use strict";({ "with": 42 }.with === 42) is true
-PASS (function(){"use strict";({ "with": 42 }.with === 42)}); true is true
-PASS "use strict";({ with: 42 }.with === 42) is true
-PASS (function(){"use strict";({ with: 42 }.with === 42)}); true is true
-PASS "use strict";({ get with(){}, set with(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get with(){}, set with(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var class; true threw exception SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
-PASS (function(){var class; true}); true threw exception SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
-PASS var class = 42; class === 42 threw exception SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
-PASS (function(){var class = 42; class === 42}); true threw exception SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
-PASS function g(class){  }; true threw exception SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
-PASS (function(){function g(class){  }; true}); true threw exception SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
-PASS /class/.test(function g(class){  }) threw exception SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
-PASS (function(){/class/.test(function g(class){  })}); true threw exception SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode.
-PASS try{}catch(class){}; true threw exception SyntaxError: Unexpected token class.
-PASS (function(){try{}catch(class){}; true}); true threw exception SyntaxError: Unexpected token class.
-PASS function class(){  }; true threw exception SyntaxError: Unexpected token class.
-PASS (function(){function class(){  }; true}); true threw exception SyntaxError: Unexpected token class.
-PASS ({ "class": 42 }.class === 42) is true
-PASS (function(){({ "class": 42 }.class === 42)}); true is true
-PASS ({ class: 42 }.class === 42) is true
-PASS (function(){({ class: 42 }.class === 42)}); true is true
-PASS ({ get class(){}, set class(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get class(){}, set class(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var class; true threw exception SyntaxError: Unexpected token ;.
-PASS (function(){"use strict";var class; true}); true threw exception SyntaxError: Unexpected token ;.
-PASS "use strict";var class = 42; class === 42 threw exception SyntaxError: Unexpected token =.
-PASS (function(){"use strict";var class = 42; class === 42}); true threw exception SyntaxError: Unexpected token =.
-PASS "use strict";function g(class){ "use strict"; }; true threw exception SyntaxError: Unexpected token ).
-PASS (function(){"use strict";function g(class){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token ).
-PASS "use strict";/class/.test(function g(class){ "use strict"; }) threw exception SyntaxError: Unexpected token ).
-PASS (function(){"use strict";/class/.test(function g(class){ "use strict"; })}); true threw exception SyntaxError: Unexpected token ).
-PASS "use strict";try{}catch(class){}; true threw exception SyntaxError: Unexpected token class.
-PASS (function(){"use strict";try{}catch(class){}; true}); true threw exception SyntaxError: Unexpected token class.
-PASS "use strict";function class(){ "use strict"; }; true threw exception SyntaxError: Unexpected token class.
-PASS (function(){"use strict";function class(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token class.
-PASS "use strict";({ "class": 42 }.class === 42) is true
-PASS (function(){"use strict";({ "class": 42 }.class === 42)}); true is true
-PASS "use strict";({ class: 42 }.class === 42) is true
-PASS (function(){"use strict";({ class: 42 }.class === 42)}); true is true
-PASS "use strict";({ get class(){}, set class(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get class(){}, set class(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var const; true threw exception SyntaxError: Unexpected token const.
-PASS (function(){var const; true}); true threw exception SyntaxError: Unexpected token const.
-PASS var const = 42; const === 42 threw exception SyntaxError: Unexpected token const.
-PASS (function(){var const = 42; const === 42}); true threw exception SyntaxError: Unexpected token const.
-PASS function g(const){  }; true threw exception SyntaxError: Unexpected token const.
-PASS (function(){function g(const){  }; true}); true threw exception SyntaxError: Unexpected token const.
-PASS /const/.test(function g(const){  }) threw exception SyntaxError: Unexpected token const.
-PASS (function(){/const/.test(function g(const){  })}); true threw exception SyntaxError: Unexpected token const.
-PASS try{}catch(const){}; true threw exception SyntaxError: Unexpected token const.
-PASS (function(){try{}catch(const){}; true}); true threw exception SyntaxError: Unexpected token const.
-PASS function const(){  }; true threw exception SyntaxError: Unexpected token const.
-PASS (function(){function const(){  }; true}); true threw exception SyntaxError: Unexpected token const.
-PASS ({ "const": 42 }.const === 42) is true
-PASS (function(){({ "const": 42 }.const === 42)}); true is true
-PASS ({ const: 42 }.const === 42) is true
-PASS (function(){({ const: 42 }.const === 42)}); true is true
-PASS ({ get const(){}, set const(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get const(){}, set const(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var const; true threw exception SyntaxError: Unexpected token const.
-PASS (function(){"use strict";var const; true}); true threw exception SyntaxError: Unexpected token const.
-PASS "use strict";var const = 42; const === 42 threw exception SyntaxError: Unexpected token const.
-PASS (function(){"use strict";var const = 42; const === 42}); true threw exception SyntaxError: Unexpected token const.
-PASS "use strict";function g(const){ "use strict"; }; true threw exception SyntaxError: Unexpected token const.
-PASS (function(){"use strict";function g(const){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token const.
-PASS "use strict";/const/.test(function g(const){ "use strict"; }) threw exception SyntaxError: Unexpected token const.
-PASS (function(){"use strict";/const/.test(function g(const){ "use strict"; })}); true threw exception SyntaxError: Unexpected token const.
-PASS "use strict";try{}catch(const){}; true threw exception SyntaxError: Unexpected token const.
-PASS (function(){"use strict";try{}catch(const){}; true}); true threw exception SyntaxError: Unexpected token const.
-PASS "use strict";function const(){ "use strict"; }; true threw exception SyntaxError: Unexpected token const.
-PASS (function(){"use strict";function const(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token const.
-PASS "use strict";({ "const": 42 }.const === 42) is true
-PASS (function(){"use strict";({ "const": 42 }.const === 42)}); true is true
-PASS "use strict";({ const: 42 }.const === 42) is true
-PASS (function(){"use strict";({ const: 42 }.const === 42)}); true is true
-PASS "use strict";({ get const(){}, set const(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get const(){}, set const(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var enum; true threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){var enum; true}); true threw exception SyntaxError: Unexpected reserved word.
-PASS var enum = 42; enum === 42 threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){var enum = 42; enum === 42}); true threw exception SyntaxError: Unexpected reserved word.
-PASS function g(enum){  }; true threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){function g(enum){  }; true}); true threw exception SyntaxError: Unexpected reserved word.
-PASS /enum/.test(function g(enum){  }) threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){/enum/.test(function g(enum){  })}); true threw exception SyntaxError: Unexpected reserved word.
-PASS try{}catch(enum){}; true threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){try{}catch(enum){}; true}); true threw exception SyntaxError: Unexpected reserved word.
-PASS function enum(){  }; true threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){function enum(){  }; true}); true threw exception SyntaxError: Unexpected reserved word.
-PASS ({ "enum": 42 }.enum === 42) is true
-PASS (function(){({ "enum": 42 }.enum === 42)}); true is true
-PASS ({ enum: 42 }.enum === 42) is true
-PASS (function(){({ enum: 42 }.enum === 42)}); true is true
-PASS ({ get enum(){}, set enum(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get enum(){}, set enum(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var enum; true threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){"use strict";var enum; true}); true threw exception SyntaxError: Unexpected reserved word.
-PASS "use strict";var enum = 42; enum === 42 threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){"use strict";var enum = 42; enum === 42}); true threw exception SyntaxError: Unexpected reserved word.
-PASS "use strict";function g(enum){ "use strict"; }; true threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){"use strict";function g(enum){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected reserved word.
-PASS "use strict";/enum/.test(function g(enum){ "use strict"; }) threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){"use strict";/enum/.test(function g(enum){ "use strict"; })}); true threw exception SyntaxError: Unexpected reserved word.
-PASS "use strict";try{}catch(enum){}; true threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){"use strict";try{}catch(enum){}; true}); true threw exception SyntaxError: Unexpected reserved word.
-PASS "use strict";function enum(){ "use strict"; }; true threw exception SyntaxError: Unexpected reserved word.
-PASS (function(){"use strict";function enum(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected reserved word.
-PASS "use strict";({ "enum": 42 }.enum === 42) is true
-PASS (function(){"use strict";({ "enum": 42 }.enum === 42)}); true is true
-PASS "use strict";({ enum: 42 }.enum === 42) is true
-PASS (function(){"use strict";({ enum: 42 }.enum === 42)}); true is true
-PASS "use strict";({ get enum(){}, set enum(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get enum(){}, set enum(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var export; true threw exception SyntaxError: Unexpected token export.
-PASS (function(){var export; true}); true threw exception SyntaxError: Unexpected token export.
-PASS var export = 42; export === 42 threw exception SyntaxError: Unexpected token export.
-PASS (function(){var export = 42; export === 42}); true threw exception SyntaxError: Unexpected token export.
-PASS function g(export){  }; true threw exception SyntaxError: Unexpected token export.
-PASS (function(){function g(export){  }; true}); true threw exception SyntaxError: Unexpected token export.
-PASS /export/.test(function g(export){  }) threw exception SyntaxError: Unexpected token export.
-PASS (function(){/export/.test(function g(export){  })}); true threw exception SyntaxError: Unexpected token export.
-PASS try{}catch(export){}; true threw exception SyntaxError: Unexpected token export.
-PASS (function(){try{}catch(export){}; true}); true threw exception SyntaxError: Unexpected token export.
-PASS function export(){  }; true threw exception SyntaxError: Unexpected token export.
-PASS (function(){function export(){  }; true}); true threw exception SyntaxError: Unexpected token export.
-PASS ({ "export": 42 }.export === 42) is true
-PASS (function(){({ "export": 42 }.export === 42)}); true is true
-PASS ({ export: 42 }.export === 42) is true
-PASS (function(){({ export: 42 }.export === 42)}); true is true
-PASS ({ get export(){}, set export(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get export(){}, set export(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var export; true threw exception SyntaxError: Unexpected token export.
-PASS (function(){"use strict";var export; true}); true threw exception SyntaxError: Unexpected token export.
-PASS "use strict";var export = 42; export === 42 threw exception SyntaxError: Unexpected token export.
-PASS (function(){"use strict";var export = 42; export === 42}); true threw exception SyntaxError: Unexpected token export.
-PASS "use strict";function g(export){ "use strict"; }; true threw exception SyntaxError: Unexpected token export.
-PASS (function(){"use strict";function g(export){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token export.
-PASS "use strict";/export/.test(function g(export){ "use strict"; }) threw exception SyntaxError: Unexpected token export.
-PASS (function(){"use strict";/export/.test(function g(export){ "use strict"; })}); true threw exception SyntaxError: Unexpected token export.
-PASS "use strict";try{}catch(export){}; true threw exception SyntaxError: Unexpected token export.
-PASS (function(){"use strict";try{}catch(export){}; true}); true threw exception SyntaxError: Unexpected token export.
-PASS "use strict";function export(){ "use strict"; }; true threw exception SyntaxError: Unexpected token export.
-PASS (function(){"use strict";function export(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token export.
-PASS "use strict";({ "export": 42 }.export === 42) is true
-PASS (function(){"use strict";({ "export": 42 }.export === 42)}); true is true
-PASS "use strict";({ export: 42 }.export === 42) is true
-PASS (function(){"use strict";({ export: 42 }.export === 42)}); true is true
-PASS "use strict";({ get export(){}, set export(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get export(){}, set export(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var extends; true threw exception SyntaxError: Unexpected token extends.
-PASS (function(){var extends; true}); true threw exception SyntaxError: Unexpected token extends.
-PASS var extends = 42; extends === 42 threw exception SyntaxError: Unexpected token extends.
-PASS (function(){var extends = 42; extends === 42}); true threw exception SyntaxError: Unexpected token extends.
-PASS function g(extends){  }; true threw exception SyntaxError: Unexpected token extends.
-PASS (function(){function g(extends){  }; true}); true threw exception SyntaxError: Unexpected token extends.
-PASS /extends/.test(function g(extends){  }) threw exception SyntaxError: Unexpected token extends.
-PASS (function(){/extends/.test(function g(extends){  })}); true threw exception SyntaxError: Unexpected token extends.
-PASS try{}catch(extends){}; true threw exception SyntaxError: Unexpected token extends.
-PASS (function(){try{}catch(extends){}; true}); true threw exception SyntaxError: Unexpected token extends.
-PASS function extends(){  }; true threw exception SyntaxError: Unexpected token extends.
-PASS (function(){function extends(){  }; true}); true threw exception SyntaxError: Unexpected token extends.
-PASS ({ "extends": 42 }.extends === 42) is true
-PASS (function(){({ "extends": 42 }.extends === 42)}); true is true
-PASS ({ extends: 42 }.extends === 42) is true
-PASS (function(){({ extends: 42 }.extends === 42)}); true is true
-PASS ({ get extends(){}, set extends(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get extends(){}, set extends(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var extends; true threw exception SyntaxError: Unexpected token extends.
-PASS (function(){"use strict";var extends; true}); true threw exception SyntaxError: Unexpected token extends.
-PASS "use strict";var extends = 42; extends === 42 threw exception SyntaxError: Unexpected token extends.
-PASS (function(){"use strict";var extends = 42; extends === 42}); true threw exception SyntaxError: Unexpected token extends.
-PASS "use strict";function g(extends){ "use strict"; }; true threw exception SyntaxError: Unexpected token extends.
-PASS (function(){"use strict";function g(extends){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token extends.
-PASS "use strict";/extends/.test(function g(extends){ "use strict"; }) threw exception SyntaxError: Unexpected token extends.
-PASS (function(){"use strict";/extends/.test(function g(extends){ "use strict"; })}); true threw exception SyntaxError: Unexpected token extends.
-PASS "use strict";try{}catch(extends){}; true threw exception SyntaxError: Unexpected token extends.
-PASS (function(){"use strict";try{}catch(extends){}; true}); true threw exception SyntaxError: Unexpected token extends.
-PASS "use strict";function extends(){ "use strict"; }; true threw exception SyntaxError: Unexpected token extends.
-PASS (function(){"use strict";function extends(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token extends.
-PASS "use strict";({ "extends": 42 }.extends === 42) is true
-PASS (function(){"use strict";({ "extends": 42 }.extends === 42)}); true is true
-PASS "use strict";({ extends: 42 }.extends === 42) is true
-PASS (function(){"use strict";({ extends: 42 }.extends === 42)}); true is true
-PASS "use strict";({ get extends(){}, set extends(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get extends(){}, set extends(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var import; true threw exception SyntaxError: Unexpected token import.
-PASS (function(){var import; true}); true threw exception SyntaxError: Unexpected token import.
-PASS var import = 42; import === 42 threw exception SyntaxError: Unexpected token import.
-PASS (function(){var import = 42; import === 42}); true threw exception SyntaxError: Unexpected token import.
-PASS function g(import){  }; true threw exception SyntaxError: Unexpected token import.
-PASS (function(){function g(import){  }; true}); true threw exception SyntaxError: Unexpected token import.
-PASS /import/.test(function g(import){  }) threw exception SyntaxError: Unexpected token import.
-PASS (function(){/import/.test(function g(import){  })}); true threw exception SyntaxError: Unexpected token import.
-PASS try{}catch(import){}; true threw exception SyntaxError: Unexpected token import.
-PASS (function(){try{}catch(import){}; true}); true threw exception SyntaxError: Unexpected token import.
-PASS function import(){  }; true threw exception SyntaxError: Unexpected token import.
-PASS (function(){function import(){  }; true}); true threw exception SyntaxError: Unexpected token import.
-PASS ({ "import": 42 }.import === 42) is true
-PASS (function(){({ "import": 42 }.import === 42)}); true is true
-PASS ({ import: 42 }.import === 42) is true
-PASS (function(){({ import: 42 }.import === 42)}); true is true
-PASS ({ get import(){}, set import(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get import(){}, set import(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var import; true threw exception SyntaxError: Unexpected token import.
-PASS (function(){"use strict";var import; true}); true threw exception SyntaxError: Unexpected token import.
-PASS "use strict";var import = 42; import === 42 threw exception SyntaxError: Unexpected token import.
-PASS (function(){"use strict";var import = 42; import === 42}); true threw exception SyntaxError: Unexpected token import.
-PASS "use strict";function g(import){ "use strict"; }; true threw exception SyntaxError: Unexpected token import.
-PASS (function(){"use strict";function g(import){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token import.
-PASS "use strict";/import/.test(function g(import){ "use strict"; }) threw exception SyntaxError: Unexpected token import.
-PASS (function(){"use strict";/import/.test(function g(import){ "use strict"; })}); true threw exception SyntaxError: Unexpected token import.
-PASS "use strict";try{}catch(import){}; true threw exception SyntaxError: Unexpected token import.
-PASS (function(){"use strict";try{}catch(import){}; true}); true threw exception SyntaxError: Unexpected token import.
-PASS "use strict";function import(){ "use strict"; }; true threw exception SyntaxError: Unexpected token import.
-PASS (function(){"use strict";function import(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token import.
-PASS "use strict";({ "import": 42 }.import === 42) is true
-PASS (function(){"use strict";({ "import": 42 }.import === 42)}); true is true
-PASS "use strict";({ import: 42 }.import === 42) is true
-PASS (function(){"use strict";({ import: 42 }.import === 42)}); true is true
-PASS "use strict";({ get import(){}, set import(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get import(){}, set import(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var super; true threw exception SyntaxError: Unexpected token super.
-PASS (function(){var super; true}); true threw exception SyntaxError: Unexpected token super.
-PASS var super = 42; super === 42 threw exception SyntaxError: Unexpected token super.
-PASS (function(){var super = 42; super === 42}); true threw exception SyntaxError: Unexpected token super.
-PASS function g(super){  }; true threw exception SyntaxError: Unexpected token super.
-PASS (function(){function g(super){  }; true}); true threw exception SyntaxError: Unexpected token super.
-PASS /super/.test(function g(super){  }) threw exception SyntaxError: Unexpected token super.
-PASS (function(){/super/.test(function g(super){  })}); true threw exception SyntaxError: Unexpected token super.
-PASS try{}catch(super){}; true threw exception SyntaxError: Unexpected token super.
-PASS (function(){try{}catch(super){}; true}); true threw exception SyntaxError: Unexpected token super.
-PASS function super(){  }; true threw exception SyntaxError: Unexpected token super.
-PASS (function(){function super(){  }; true}); true threw exception SyntaxError: Unexpected token super.
-PASS ({ "super": 42 }.super === 42) is true
-PASS (function(){({ "super": 42 }.super === 42)}); true is true
-PASS ({ super: 42 }.super === 42) is true
-PASS (function(){({ super: 42 }.super === 42)}); true is true
-PASS ({ get super(){}, set super(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get super(){}, set super(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var super; true threw exception SyntaxError: Unexpected token super.
-PASS (function(){"use strict";var super; true}); true threw exception SyntaxError: Unexpected token super.
-PASS "use strict";var super = 42; super === 42 threw exception SyntaxError: Unexpected token super.
-PASS (function(){"use strict";var super = 42; super === 42}); true threw exception SyntaxError: Unexpected token super.
-PASS "use strict";function g(super){ "use strict"; }; true threw exception SyntaxError: Unexpected token super.
-PASS (function(){"use strict";function g(super){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token super.
-PASS "use strict";/super/.test(function g(super){ "use strict"; }) threw exception SyntaxError: Unexpected token super.
-PASS (function(){"use strict";/super/.test(function g(super){ "use strict"; })}); true threw exception SyntaxError: Unexpected token super.
-PASS "use strict";try{}catch(super){}; true threw exception SyntaxError: Unexpected token super.
-PASS (function(){"use strict";try{}catch(super){}; true}); true threw exception SyntaxError: Unexpected token super.
-PASS "use strict";function super(){ "use strict"; }; true threw exception SyntaxError: Unexpected token super.
-PASS (function(){"use strict";function super(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected token super.
-PASS "use strict";({ "super": 42 }.super === 42) is true
-PASS (function(){"use strict";({ "super": 42 }.super === 42)}); true is true
-PASS "use strict";({ super: 42 }.super === 42) is true
-PASS (function(){"use strict";({ super: 42 }.super === 42)}); true is true
-PASS "use strict";({ get super(){}, set super(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get super(){}, set super(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var implements; true is true
-PASS (function(){var implements; true}); true is true
-PASS var implements = 42; implements === 42 is true
-PASS (function(){var implements = 42; implements === 42}); true is true
-PASS function g(implements){  }; true is true
-PASS (function(){function g(implements){  }; true}); true is true
-PASS /implements/.test(function g(implements){  }) is true
-PASS (function(){/implements/.test(function g(implements){  })}); true is true
-PASS try{}catch(implements){}; true is true
-PASS (function(){try{}catch(implements){}; true}); true is true
-PASS function implements(){  }; true is true
-PASS (function(){function implements(){  }; true}); true is true
-PASS ({ "implements": 42 }.implements === 42) is true
-PASS (function(){({ "implements": 42 }.implements === 42)}); true is true
-PASS ({ implements: 42 }.implements === 42) is true
-PASS (function(){({ implements: 42 }.implements === 42)}); true is true
-PASS ({ get implements(){}, set implements(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get implements(){}, set implements(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var implements; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var implements; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var implements = 42; implements === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var implements = 42; implements === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(implements){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(implements){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/implements/.test(function g(implements){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/implements/.test(function g(implements){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(implements){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(implements){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function implements(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function implements(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "implements": 42 }.implements === 42) is true
-PASS (function(){"use strict";({ "implements": 42 }.implements === 42)}); true is true
-PASS "use strict";({ implements: 42 }.implements === 42) is true
-PASS (function(){"use strict";({ implements: 42 }.implements === 42)}); true is true
-PASS "use strict";({ get implements(){}, set implements(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get implements(){}, set implements(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var let; true is true
-PASS (function(){var let; true}); true is true
-PASS var let = 42; let === 42 is true
-PASS (function(){var let = 42; let === 42}); true is true
-PASS function g(let){  }; true is true
-PASS (function(){function g(let){  }; true}); true is true
-PASS /let/.test(function g(let){  }) is true
-PASS (function(){/let/.test(function g(let){  })}); true is true
-PASS try{}catch(let){}; true is true
-PASS (function(){try{}catch(let){}; true}); true is true
-PASS function let(){  }; true is true
-PASS (function(){function let(){  }; true}); true is true
-PASS ({ "let": 42 }.let === 42) is true
-PASS (function(){({ "let": 42 }.let === 42)}); true is true
-PASS ({ let: 42 }.let === 42) is true
-PASS (function(){({ let: 42 }.let === 42)}); true is true
-PASS ({ get let(){}, set let(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get let(){}, set let(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var let; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var let; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var let = 42; let === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var let = 42; let === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(let){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(let){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/let/.test(function g(let){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/let/.test(function g(let){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(let){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(let){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function let(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function let(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "let": 42 }.let === 42) is true
-PASS (function(){"use strict";({ "let": 42 }.let === 42)}); true is true
-PASS "use strict";({ let: 42 }.let === 42) is true
-PASS (function(){"use strict";({ let: 42 }.let === 42)}); true is true
-PASS "use strict";({ get let(){}, set let(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get let(){}, set let(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var private; true is true
-PASS (function(){var private; true}); true is true
-PASS var private = 42; private === 42 is true
-PASS (function(){var private = 42; private === 42}); true is true
-PASS function g(private){  }; true is true
-PASS (function(){function g(private){  }; true}); true is true
-PASS /private/.test(function g(private){  }) is true
-PASS (function(){/private/.test(function g(private){  })}); true is true
-PASS try{}catch(private){}; true is true
-PASS (function(){try{}catch(private){}; true}); true is true
-PASS function private(){  }; true is true
-PASS (function(){function private(){  }; true}); true is true
-PASS ({ "private": 42 }.private === 42) is true
-PASS (function(){({ "private": 42 }.private === 42)}); true is true
-PASS ({ private: 42 }.private === 42) is true
-PASS (function(){({ private: 42 }.private === 42)}); true is true
-PASS ({ get private(){}, set private(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get private(){}, set private(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var private; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var private; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var private = 42; private === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var private = 42; private === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(private){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(private){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/private/.test(function g(private){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/private/.test(function g(private){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(private){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(private){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function private(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function private(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "private": 42 }.private === 42) is true
-PASS (function(){"use strict";({ "private": 42 }.private === 42)}); true is true
-PASS "use strict";({ private: 42 }.private === 42) is true
-PASS (function(){"use strict";({ private: 42 }.private === 42)}); true is true
-PASS "use strict";({ get private(){}, set private(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get private(){}, set private(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var public; true is true
-PASS (function(){var public; true}); true is true
-PASS var public = 42; public === 42 is true
-PASS (function(){var public = 42; public === 42}); true is true
-PASS function g(public){  }; true is true
-PASS (function(){function g(public){  }; true}); true is true
-PASS /public/.test(function g(public){  }) is true
-PASS (function(){/public/.test(function g(public){  })}); true is true
-PASS try{}catch(public){}; true is true
-PASS (function(){try{}catch(public){}; true}); true is true
-PASS function public(){  }; true is true
-PASS (function(){function public(){  }; true}); true is true
-PASS ({ "public": 42 }.public === 42) is true
-PASS (function(){({ "public": 42 }.public === 42)}); true is true
-PASS ({ public: 42 }.public === 42) is true
-PASS (function(){({ public: 42 }.public === 42)}); true is true
-PASS ({ get public(){}, set public(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get public(){}, set public(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var public; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var public; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var public = 42; public === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var public = 42; public === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(public){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(public){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/public/.test(function g(public){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/public/.test(function g(public){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(public){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(public){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function public(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function public(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "public": 42 }.public === 42) is true
-PASS (function(){"use strict";({ "public": 42 }.public === 42)}); true is true
-PASS "use strict";({ public: 42 }.public === 42) is true
-PASS (function(){"use strict";({ public: 42 }.public === 42)}); true is true
-PASS "use strict";({ get public(){}, set public(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get public(){}, set public(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var yield; true is true
-PASS (function(){var yield; true}); true is true
-PASS var yield = 42; yield === 42 is true
-PASS (function(){var yield = 42; yield === 42}); true is true
-PASS function g(yield){  }; true is true
-PASS (function(){function g(yield){  }; true}); true is true
-PASS /yield/.test(function g(yield){  }) is true
-PASS (function(){/yield/.test(function g(yield){  })}); true is true
-PASS try{}catch(yield){}; true is true
-PASS (function(){try{}catch(yield){}; true}); true is true
-PASS function yield(){  }; true is true
-PASS (function(){function yield(){  }; true}); true is true
-PASS ({ "yield": 42 }.yield === 42) is true
-PASS (function(){({ "yield": 42 }.yield === 42)}); true is true
-PASS ({ yield: 42 }.yield === 42) is true
-PASS (function(){({ yield: 42 }.yield === 42)}); true is true
-PASS ({ get yield(){}, set yield(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get yield(){}, set yield(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var yield; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var yield; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var yield = 42; yield === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var yield = 42; yield === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(yield){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(yield){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/yield/.test(function g(yield){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/yield/.test(function g(yield){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(yield){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(yield){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function yield(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function yield(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "yield": 42 }.yield === 42) is true
-PASS (function(){"use strict";({ "yield": 42 }.yield === 42)}); true is true
-PASS "use strict";({ yield: 42 }.yield === 42) is true
-PASS (function(){"use strict";({ yield: 42 }.yield === 42)}); true is true
-PASS "use strict";({ get yield(){}, set yield(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get yield(){}, set yield(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var interface; true is true
-PASS (function(){var interface; true}); true is true
-PASS var interface = 42; interface === 42 is true
-PASS (function(){var interface = 42; interface === 42}); true is true
-PASS function g(interface){  }; true is true
-PASS (function(){function g(interface){  }; true}); true is true
-PASS /interface/.test(function g(interface){  }) is true
-PASS (function(){/interface/.test(function g(interface){  })}); true is true
-PASS try{}catch(interface){}; true is true
-PASS (function(){try{}catch(interface){}; true}); true is true
-PASS function interface(){  }; true is true
-PASS (function(){function interface(){  }; true}); true is true
-PASS ({ "interface": 42 }.interface === 42) is true
-PASS (function(){({ "interface": 42 }.interface === 42)}); true is true
-PASS ({ interface: 42 }.interface === 42) is true
-PASS (function(){({ interface: 42 }.interface === 42)}); true is true
-PASS ({ get interface(){}, set interface(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get interface(){}, set interface(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var interface; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var interface; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var interface = 42; interface === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var interface = 42; interface === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(interface){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(interface){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/interface/.test(function g(interface){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/interface/.test(function g(interface){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(interface){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(interface){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function interface(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function interface(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "interface": 42 }.interface === 42) is true
-PASS (function(){"use strict";({ "interface": 42 }.interface === 42)}); true is true
-PASS "use strict";({ interface: 42 }.interface === 42) is true
-PASS (function(){"use strict";({ interface: 42 }.interface === 42)}); true is true
-PASS "use strict";({ get interface(){}, set interface(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get interface(){}, set interface(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var package; true is true
-PASS (function(){var package; true}); true is true
-PASS var package = 42; package === 42 is true
-PASS (function(){var package = 42; package === 42}); true is true
-PASS function g(package){  }; true is true
-PASS (function(){function g(package){  }; true}); true is true
-PASS /package/.test(function g(package){  }) is true
-PASS (function(){/package/.test(function g(package){  })}); true is true
-PASS try{}catch(package){}; true is true
-PASS (function(){try{}catch(package){}; true}); true is true
-PASS function package(){  }; true is true
-PASS (function(){function package(){  }; true}); true is true
-PASS ({ "package": 42 }.package === 42) is true
-PASS (function(){({ "package": 42 }.package === 42)}); true is true
-PASS ({ package: 42 }.package === 42) is true
-PASS (function(){({ package: 42 }.package === 42)}); true is true
-PASS ({ get package(){}, set package(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get package(){}, set package(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var package; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var package; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var package = 42; package === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var package = 42; package === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(package){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(package){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/package/.test(function g(package){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/package/.test(function g(package){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(package){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(package){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function package(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function package(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "package": 42 }.package === 42) is true
-PASS (function(){"use strict";({ "package": 42 }.package === 42)}); true is true
-PASS "use strict";({ package: 42 }.package === 42) is true
-PASS (function(){"use strict";({ package: 42 }.package === 42)}); true is true
-PASS "use strict";({ get package(){}, set package(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get package(){}, set package(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var protected; true is true
-PASS (function(){var protected; true}); true is true
-PASS var protected = 42; protected === 42 is true
-PASS (function(){var protected = 42; protected === 42}); true is true
-PASS function g(protected){  }; true is true
-PASS (function(){function g(protected){  }; true}); true is true
-PASS /protected/.test(function g(protected){  }) is true
-PASS (function(){/protected/.test(function g(protected){  })}); true is true
-PASS try{}catch(protected){}; true is true
-PASS (function(){try{}catch(protected){}; true}); true is true
-PASS function protected(){  }; true is true
-PASS (function(){function protected(){  }; true}); true is true
-PASS ({ "protected": 42 }.protected === 42) is true
-PASS (function(){({ "protected": 42 }.protected === 42)}); true is true
-PASS ({ protected: 42 }.protected === 42) is true
-PASS (function(){({ protected: 42 }.protected === 42)}); true is true
-PASS ({ get protected(){}, set protected(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get protected(){}, set protected(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var protected; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var protected; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var protected = 42; protected === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var protected = 42; protected === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(protected){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(protected){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/protected/.test(function g(protected){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/protected/.test(function g(protected){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(protected){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(protected){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function protected(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function protected(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "protected": 42 }.protected === 42) is true
-PASS (function(){"use strict";({ "protected": 42 }.protected === 42)}); true is true
-PASS "use strict";({ protected: 42 }.protected === 42) is true
-PASS (function(){"use strict";({ protected: 42 }.protected === 42)}); true is true
-PASS "use strict";({ get protected(){}, set protected(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get protected(){}, set protected(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var static; true is true
-PASS (function(){var static; true}); true is true
-PASS var static = 42; static === 42 is true
-PASS (function(){var static = 42; static === 42}); true is true
-PASS function g(static){  }; true is true
-PASS (function(){function g(static){  }; true}); true is true
-PASS /static/.test(function g(static){  }) is true
-PASS (function(){/static/.test(function g(static){  })}); true is true
-PASS try{}catch(static){}; true is true
-PASS (function(){try{}catch(static){}; true}); true is true
-PASS function static(){  }; true is true
-PASS (function(){function static(){  }; true}); true is true
-PASS ({ "static": 42 }.static === 42) is true
-PASS (function(){({ "static": 42 }.static === 42)}); true is true
-PASS ({ static: 42 }.static === 42) is true
-PASS (function(){({ static: 42 }.static === 42)}); true is true
-PASS ({ get static(){}, set static(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get static(){}, set static(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var static; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var static; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";var static = 42; static === 42 threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";var static = 42; static === 42}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function g(static){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function g(static){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";/static/.test(function g(static){ "use strict"; }) threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";/static/.test(function g(static){ "use strict"; })}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";try{}catch(static){}; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";try{}catch(static){}; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";function static(){ "use strict"; }; true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS (function(){"use strict";function static(){ "use strict"; }; true}); true threw exception SyntaxError: Unexpected strict mode reserved word.
-PASS "use strict";({ "static": 42 }.static === 42) is true
-PASS (function(){"use strict";({ "static": 42 }.static === 42)}); true is true
-PASS "use strict";({ static: 42 }.static === 42) is true
-PASS (function(){"use strict";({ static: 42 }.static === 42)}); true is true
-PASS "use strict";({ get static(){}, set static(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get static(){}, set static(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var abstract; true is true
-PASS (function(){var abstract; true}); true is true
-PASS var abstract = 42; abstract === 42 is true
-PASS (function(){var abstract = 42; abstract === 42}); true is true
-PASS function g(abstract){  }; true is true
-PASS (function(){function g(abstract){  }; true}); true is true
-PASS /abstract/.test(function g(abstract){  }) is true
-PASS (function(){/abstract/.test(function g(abstract){  })}); true is true
-PASS try{}catch(abstract){}; true is true
-PASS (function(){try{}catch(abstract){}; true}); true is true
-PASS function abstract(){  }; true is true
-PASS (function(){function abstract(){  }; true}); true is true
-PASS ({ "abstract": 42 }.abstract === 42) is true
-PASS (function(){({ "abstract": 42 }.abstract === 42)}); true is true
-PASS ({ abstract: 42 }.abstract === 42) is true
-PASS (function(){({ abstract: 42 }.abstract === 42)}); true is true
-PASS ({ get abstract(){}, set abstract(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get abstract(){}, set abstract(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var abstract; true is true
-PASS (function(){"use strict";var abstract; true}); true is true
-PASS "use strict";var abstract = 42; abstract === 42 is true
-PASS (function(){"use strict";var abstract = 42; abstract === 42}); true is true
-PASS "use strict";function g(abstract){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(abstract){ "use strict"; }; true}); true is true
-PASS "use strict";/abstract/.test(function g(abstract){ "use strict"; }) is true
-PASS (function(){"use strict";/abstract/.test(function g(abstract){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(abstract){}; true is true
-PASS (function(){"use strict";try{}catch(abstract){}; true}); true is true
-PASS "use strict";function abstract(){ "use strict"; }; true is true
-PASS (function(){"use strict";function abstract(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "abstract": 42 }.abstract === 42) is true
-PASS (function(){"use strict";({ "abstract": 42 }.abstract === 42)}); true is true
-PASS "use strict";({ abstract: 42 }.abstract === 42) is true
-PASS (function(){"use strict";({ abstract: 42 }.abstract === 42)}); true is true
-PASS "use strict";({ get abstract(){}, set abstract(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get abstract(){}, set abstract(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var boolean; true is true
-PASS (function(){var boolean; true}); true is true
-PASS var boolean = 42; boolean === 42 is true
-PASS (function(){var boolean = 42; boolean === 42}); true is true
-PASS function g(boolean){  }; true is true
-PASS (function(){function g(boolean){  }; true}); true is true
-PASS /boolean/.test(function g(boolean){  }) is true
-PASS (function(){/boolean/.test(function g(boolean){  })}); true is true
-PASS try{}catch(boolean){}; true is true
-PASS (function(){try{}catch(boolean){}; true}); true is true
-PASS function boolean(){  }; true is true
-PASS (function(){function boolean(){  }; true}); true is true
-PASS ({ "boolean": 42 }.boolean === 42) is true
-PASS (function(){({ "boolean": 42 }.boolean === 42)}); true is true
-PASS ({ boolean: 42 }.boolean === 42) is true
-PASS (function(){({ boolean: 42 }.boolean === 42)}); true is true
-PASS ({ get boolean(){}, set boolean(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get boolean(){}, set boolean(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var boolean; true is true
-PASS (function(){"use strict";var boolean; true}); true is true
-PASS "use strict";var boolean = 42; boolean === 42 is true
-PASS (function(){"use strict";var boolean = 42; boolean === 42}); true is true
-PASS "use strict";function g(boolean){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(boolean){ "use strict"; }; true}); true is true
-PASS "use strict";/boolean/.test(function g(boolean){ "use strict"; }) is true
-PASS (function(){"use strict";/boolean/.test(function g(boolean){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(boolean){}; true is true
-PASS (function(){"use strict";try{}catch(boolean){}; true}); true is true
-PASS "use strict";function boolean(){ "use strict"; }; true is true
-PASS (function(){"use strict";function boolean(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "boolean": 42 }.boolean === 42) is true
-PASS (function(){"use strict";({ "boolean": 42 }.boolean === 42)}); true is true
-PASS "use strict";({ boolean: 42 }.boolean === 42) is true
-PASS (function(){"use strict";({ boolean: 42 }.boolean === 42)}); true is true
-PASS "use strict";({ get boolean(){}, set boolean(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get boolean(){}, set boolean(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var byte; true is true
-PASS (function(){var byte; true}); true is true
-PASS var byte = 42; byte === 42 is true
-PASS (function(){var byte = 42; byte === 42}); true is true
-PASS function g(byte){  }; true is true
-PASS (function(){function g(byte){  }; true}); true is true
-PASS /byte/.test(function g(byte){  }) is true
-PASS (function(){/byte/.test(function g(byte){  })}); true is true
-PASS try{}catch(byte){}; true is true
-PASS (function(){try{}catch(byte){}; true}); true is true
-PASS function byte(){  }; true is true
-PASS (function(){function byte(){  }; true}); true is true
-PASS ({ "byte": 42 }.byte === 42) is true
-PASS (function(){({ "byte": 42 }.byte === 42)}); true is true
-PASS ({ byte: 42 }.byte === 42) is true
-PASS (function(){({ byte: 42 }.byte === 42)}); true is true
-PASS ({ get byte(){}, set byte(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get byte(){}, set byte(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var byte; true is true
-PASS (function(){"use strict";var byte; true}); true is true
-PASS "use strict";var byte = 42; byte === 42 is true
-PASS (function(){"use strict";var byte = 42; byte === 42}); true is true
-PASS "use strict";function g(byte){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(byte){ "use strict"; }; true}); true is true
-PASS "use strict";/byte/.test(function g(byte){ "use strict"; }) is true
-PASS (function(){"use strict";/byte/.test(function g(byte){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(byte){}; true is true
-PASS (function(){"use strict";try{}catch(byte){}; true}); true is true
-PASS "use strict";function byte(){ "use strict"; }; true is true
-PASS (function(){"use strict";function byte(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "byte": 42 }.byte === 42) is true
-PASS (function(){"use strict";({ "byte": 42 }.byte === 42)}); true is true
-PASS "use strict";({ byte: 42 }.byte === 42) is true
-PASS (function(){"use strict";({ byte: 42 }.byte === 42)}); true is true
-PASS "use strict";({ get byte(){}, set byte(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get byte(){}, set byte(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var char; true is true
-PASS (function(){var char; true}); true is true
-PASS var char = 42; char === 42 is true
-PASS (function(){var char = 42; char === 42}); true is true
-PASS function g(char){  }; true is true
-PASS (function(){function g(char){  }; true}); true is true
-PASS /char/.test(function g(char){  }) is true
-PASS (function(){/char/.test(function g(char){  })}); true is true
-PASS try{}catch(char){}; true is true
-PASS (function(){try{}catch(char){}; true}); true is true
-PASS function char(){  }; true is true
-PASS (function(){function char(){  }; true}); true is true
-PASS ({ "char": 42 }.char === 42) is true
-PASS (function(){({ "char": 42 }.char === 42)}); true is true
-PASS ({ char: 42 }.char === 42) is true
-PASS (function(){({ char: 42 }.char === 42)}); true is true
-PASS ({ get char(){}, set char(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get char(){}, set char(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var char; true is true
-PASS (function(){"use strict";var char; true}); true is true
-PASS "use strict";var char = 42; char === 42 is true
-PASS (function(){"use strict";var char = 42; char === 42}); true is true
-PASS "use strict";function g(char){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(char){ "use strict"; }; true}); true is true
-PASS "use strict";/char/.test(function g(char){ "use strict"; }) is true
-PASS (function(){"use strict";/char/.test(function g(char){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(char){}; true is true
-PASS (function(){"use strict";try{}catch(char){}; true}); true is true
-PASS "use strict";function char(){ "use strict"; }; true is true
-PASS (function(){"use strict";function char(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "char": 42 }.char === 42) is true
-PASS (function(){"use strict";({ "char": 42 }.char === 42)}); true is true
-PASS "use strict";({ char: 42 }.char === 42) is true
-PASS (function(){"use strict";({ char: 42 }.char === 42)}); true is true
-PASS "use strict";({ get char(){}, set char(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get char(){}, set char(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var double; true is true
-PASS (function(){var double; true}); true is true
-PASS var double = 42; double === 42 is true
-PASS (function(){var double = 42; double === 42}); true is true
-PASS function g(double){  }; true is true
-PASS (function(){function g(double){  }; true}); true is true
-PASS /double/.test(function g(double){  }) is true
-PASS (function(){/double/.test(function g(double){  })}); true is true
-PASS try{}catch(double){}; true is true
-PASS (function(){try{}catch(double){}; true}); true is true
-PASS function double(){  }; true is true
-PASS (function(){function double(){  }; true}); true is true
-PASS ({ "double": 42 }.double === 42) is true
-PASS (function(){({ "double": 42 }.double === 42)}); true is true
-PASS ({ double: 42 }.double === 42) is true
-PASS (function(){({ double: 42 }.double === 42)}); true is true
-PASS ({ get double(){}, set double(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get double(){}, set double(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var double; true is true
-PASS (function(){"use strict";var double; true}); true is true
-PASS "use strict";var double = 42; double === 42 is true
-PASS (function(){"use strict";var double = 42; double === 42}); true is true
-PASS "use strict";function g(double){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(double){ "use strict"; }; true}); true is true
-PASS "use strict";/double/.test(function g(double){ "use strict"; }) is true
-PASS (function(){"use strict";/double/.test(function g(double){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(double){}; true is true
-PASS (function(){"use strict";try{}catch(double){}; true}); true is true
-PASS "use strict";function double(){ "use strict"; }; true is true
-PASS (function(){"use strict";function double(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "double": 42 }.double === 42) is true
-PASS (function(){"use strict";({ "double": 42 }.double === 42)}); true is true
-PASS "use strict";({ double: 42 }.double === 42) is true
-PASS (function(){"use strict";({ double: 42 }.double === 42)}); true is true
-PASS "use strict";({ get double(){}, set double(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get double(){}, set double(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var final; true is true
-PASS (function(){var final; true}); true is true
-PASS var final = 42; final === 42 is true
-PASS (function(){var final = 42; final === 42}); true is true
-PASS function g(final){  }; true is true
-PASS (function(){function g(final){  }; true}); true is true
-PASS /final/.test(function g(final){  }) is true
-PASS (function(){/final/.test(function g(final){  })}); true is true
-PASS try{}catch(final){}; true is true
-PASS (function(){try{}catch(final){}; true}); true is true
-PASS function final(){  }; true is true
-PASS (function(){function final(){  }; true}); true is true
-PASS ({ "final": 42 }.final === 42) is true
-PASS (function(){({ "final": 42 }.final === 42)}); true is true
-PASS ({ final: 42 }.final === 42) is true
-PASS (function(){({ final: 42 }.final === 42)}); true is true
-PASS ({ get final(){}, set final(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get final(){}, set final(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var final; true is true
-PASS (function(){"use strict";var final; true}); true is true
-PASS "use strict";var final = 42; final === 42 is true
-PASS (function(){"use strict";var final = 42; final === 42}); true is true
-PASS "use strict";function g(final){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(final){ "use strict"; }; true}); true is true
-PASS "use strict";/final/.test(function g(final){ "use strict"; }) is true
-PASS (function(){"use strict";/final/.test(function g(final){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(final){}; true is true
-PASS (function(){"use strict";try{}catch(final){}; true}); true is true
-PASS "use strict";function final(){ "use strict"; }; true is true
-PASS (function(){"use strict";function final(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "final": 42 }.final === 42) is true
-PASS (function(){"use strict";({ "final": 42 }.final === 42)}); true is true
-PASS "use strict";({ final: 42 }.final === 42) is true
-PASS (function(){"use strict";({ final: 42 }.final === 42)}); true is true
-PASS "use strict";({ get final(){}, set final(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get final(){}, set final(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var float; true is true
-PASS (function(){var float; true}); true is true
-PASS var float = 42; float === 42 is true
-PASS (function(){var float = 42; float === 42}); true is true
-PASS function g(float){  }; true is true
-PASS (function(){function g(float){  }; true}); true is true
-PASS /float/.test(function g(float){  }) is true
-PASS (function(){/float/.test(function g(float){  })}); true is true
-PASS try{}catch(float){}; true is true
-PASS (function(){try{}catch(float){}; true}); true is true
-PASS function float(){  }; true is true
-PASS (function(){function float(){  }; true}); true is true
-PASS ({ "float": 42 }.float === 42) is true
-PASS (function(){({ "float": 42 }.float === 42)}); true is true
-PASS ({ float: 42 }.float === 42) is true
-PASS (function(){({ float: 42 }.float === 42)}); true is true
-PASS ({ get float(){}, set float(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get float(){}, set float(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var float; true is true
-PASS (function(){"use strict";var float; true}); true is true
-PASS "use strict";var float = 42; float === 42 is true
-PASS (function(){"use strict";var float = 42; float === 42}); true is true
-PASS "use strict";function g(float){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(float){ "use strict"; }; true}); true is true
-PASS "use strict";/float/.test(function g(float){ "use strict"; }) is true
-PASS (function(){"use strict";/float/.test(function g(float){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(float){}; true is true
-PASS (function(){"use strict";try{}catch(float){}; true}); true is true
-PASS "use strict";function float(){ "use strict"; }; true is true
-PASS (function(){"use strict";function float(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "float": 42 }.float === 42) is true
-PASS (function(){"use strict";({ "float": 42 }.float === 42)}); true is true
-PASS "use strict";({ float: 42 }.float === 42) is true
-PASS (function(){"use strict";({ float: 42 }.float === 42)}); true is true
-PASS "use strict";({ get float(){}, set float(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get float(){}, set float(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var goto; true is true
-PASS (function(){var goto; true}); true is true
-PASS var goto = 42; goto === 42 is true
-PASS (function(){var goto = 42; goto === 42}); true is true
-PASS function g(goto){  }; true is true
-PASS (function(){function g(goto){  }; true}); true is true
-PASS /goto/.test(function g(goto){  }) is true
-PASS (function(){/goto/.test(function g(goto){  })}); true is true
-PASS try{}catch(goto){}; true is true
-PASS (function(){try{}catch(goto){}; true}); true is true
-PASS function goto(){  }; true is true
-PASS (function(){function goto(){  }; true}); true is true
-PASS ({ "goto": 42 }.goto === 42) is true
-PASS (function(){({ "goto": 42 }.goto === 42)}); true is true
-PASS ({ goto: 42 }.goto === 42) is true
-PASS (function(){({ goto: 42 }.goto === 42)}); true is true
-PASS ({ get goto(){}, set goto(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get goto(){}, set goto(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var goto; true is true
-PASS (function(){"use strict";var goto; true}); true is true
-PASS "use strict";var goto = 42; goto === 42 is true
-PASS (function(){"use strict";var goto = 42; goto === 42}); true is true
-PASS "use strict";function g(goto){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(goto){ "use strict"; }; true}); true is true
-PASS "use strict";/goto/.test(function g(goto){ "use strict"; }) is true
-PASS (function(){"use strict";/goto/.test(function g(goto){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(goto){}; true is true
-PASS (function(){"use strict";try{}catch(goto){}; true}); true is true
-PASS "use strict";function goto(){ "use strict"; }; true is true
-PASS (function(){"use strict";function goto(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "goto": 42 }.goto === 42) is true
-PASS (function(){"use strict";({ "goto": 42 }.goto === 42)}); true is true
-PASS "use strict";({ goto: 42 }.goto === 42) is true
-PASS (function(){"use strict";({ goto: 42 }.goto === 42)}); true is true
-PASS "use strict";({ get goto(){}, set goto(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get goto(){}, set goto(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var int; true is true
-PASS (function(){var int; true}); true is true
-PASS var int = 42; int === 42 is true
-PASS (function(){var int = 42; int === 42}); true is true
-PASS function g(int){  }; true is true
-PASS (function(){function g(int){  }; true}); true is true
-PASS /int/.test(function g(int){  }) is true
-PASS (function(){/int/.test(function g(int){  })}); true is true
-PASS try{}catch(int){}; true is true
-PASS (function(){try{}catch(int){}; true}); true is true
-PASS function int(){  }; true is true
-PASS (function(){function int(){  }; true}); true is true
-PASS ({ "int": 42 }.int === 42) is true
-PASS (function(){({ "int": 42 }.int === 42)}); true is true
-PASS ({ int: 42 }.int === 42) is true
-PASS (function(){({ int: 42 }.int === 42)}); true is true
-PASS ({ get int(){}, set int(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get int(){}, set int(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var int; true is true
-PASS (function(){"use strict";var int; true}); true is true
-PASS "use strict";var int = 42; int === 42 is true
-PASS (function(){"use strict";var int = 42; int === 42}); true is true
-PASS "use strict";function g(int){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(int){ "use strict"; }; true}); true is true
-PASS "use strict";/int/.test(function g(int){ "use strict"; }) is true
-PASS (function(){"use strict";/int/.test(function g(int){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(int){}; true is true
-PASS (function(){"use strict";try{}catch(int){}; true}); true is true
-PASS "use strict";function int(){ "use strict"; }; true is true
-PASS (function(){"use strict";function int(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "int": 42 }.int === 42) is true
-PASS (function(){"use strict";({ "int": 42 }.int === 42)}); true is true
-PASS "use strict";({ int: 42 }.int === 42) is true
-PASS (function(){"use strict";({ int: 42 }.int === 42)}); true is true
-PASS "use strict";({ get int(){}, set int(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get int(){}, set int(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var long; true is true
-PASS (function(){var long; true}); true is true
-PASS var long = 42; long === 42 is true
-PASS (function(){var long = 42; long === 42}); true is true
-PASS function g(long){  }; true is true
-PASS (function(){function g(long){  }; true}); true is true
-PASS /long/.test(function g(long){  }) is true
-PASS (function(){/long/.test(function g(long){  })}); true is true
-PASS try{}catch(long){}; true is true
-PASS (function(){try{}catch(long){}; true}); true is true
-PASS function long(){  }; true is true
-PASS (function(){function long(){  }; true}); true is true
-PASS ({ "long": 42 }.long === 42) is true
-PASS (function(){({ "long": 42 }.long === 42)}); true is true
-PASS ({ long: 42 }.long === 42) is true
-PASS (function(){({ long: 42 }.long === 42)}); true is true
-PASS ({ get long(){}, set long(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get long(){}, set long(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var long; true is true
-PASS (function(){"use strict";var long; true}); true is true
-PASS "use strict";var long = 42; long === 42 is true
-PASS (function(){"use strict";var long = 42; long === 42}); true is true
-PASS "use strict";function g(long){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(long){ "use strict"; }; true}); true is true
-PASS "use strict";/long/.test(function g(long){ "use strict"; }) is true
-PASS (function(){"use strict";/long/.test(function g(long){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(long){}; true is true
-PASS (function(){"use strict";try{}catch(long){}; true}); true is true
-PASS "use strict";function long(){ "use strict"; }; true is true
-PASS (function(){"use strict";function long(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "long": 42 }.long === 42) is true
-PASS (function(){"use strict";({ "long": 42 }.long === 42)}); true is true
-PASS "use strict";({ long: 42 }.long === 42) is true
-PASS (function(){"use strict";({ long: 42 }.long === 42)}); true is true
-PASS "use strict";({ get long(){}, set long(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get long(){}, set long(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var native; true is true
-PASS (function(){var native; true}); true is true
-PASS var native = 42; native === 42 is true
-PASS (function(){var native = 42; native === 42}); true is true
-PASS function g(native){  }; true is true
-PASS (function(){function g(native){  }; true}); true is true
-PASS /native/.test(function g(native){  }) is true
-PASS (function(){/native/.test(function g(native){  })}); true is true
-PASS try{}catch(native){}; true is true
-PASS (function(){try{}catch(native){}; true}); true is true
-PASS function native(){  }; true is true
-PASS (function(){function native(){  }; true}); true is true
-PASS ({ "native": 42 }.native === 42) is true
-PASS (function(){({ "native": 42 }.native === 42)}); true is true
-PASS ({ native: 42 }.native === 42) is true
-PASS (function(){({ native: 42 }.native === 42)}); true is true
-PASS ({ get native(){}, set native(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get native(){}, set native(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var native; true is true
-PASS (function(){"use strict";var native; true}); true is true
-PASS "use strict";var native = 42; native === 42 is true
-PASS (function(){"use strict";var native = 42; native === 42}); true is true
-PASS "use strict";function g(native){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(native){ "use strict"; }; true}); true is true
-PASS "use strict";/native/.test(function g(native){ "use strict"; }) is true
-PASS (function(){"use strict";/native/.test(function g(native){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(native){}; true is true
-PASS (function(){"use strict";try{}catch(native){}; true}); true is true
-PASS "use strict";function native(){ "use strict"; }; true is true
-PASS (function(){"use strict";function native(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "native": 42 }.native === 42) is true
-PASS (function(){"use strict";({ "native": 42 }.native === 42)}); true is true
-PASS "use strict";({ native: 42 }.native === 42) is true
-PASS (function(){"use strict";({ native: 42 }.native === 42)}); true is true
-PASS "use strict";({ get native(){}, set native(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get native(){}, set native(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var short; true is true
-PASS (function(){var short; true}); true is true
-PASS var short = 42; short === 42 is true
-PASS (function(){var short = 42; short === 42}); true is true
-PASS function g(short){  }; true is true
-PASS (function(){function g(short){  }; true}); true is true
-PASS /short/.test(function g(short){  }) is true
-PASS (function(){/short/.test(function g(short){  })}); true is true
-PASS try{}catch(short){}; true is true
-PASS (function(){try{}catch(short){}; true}); true is true
-PASS function short(){  }; true is true
-PASS (function(){function short(){  }; true}); true is true
-PASS ({ "short": 42 }.short === 42) is true
-PASS (function(){({ "short": 42 }.short === 42)}); true is true
-PASS ({ short: 42 }.short === 42) is true
-PASS (function(){({ short: 42 }.short === 42)}); true is true
-PASS ({ get short(){}, set short(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get short(){}, set short(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var short; true is true
-PASS (function(){"use strict";var short; true}); true is true
-PASS "use strict";var short = 42; short === 42 is true
-PASS (function(){"use strict";var short = 42; short === 42}); true is true
-PASS "use strict";function g(short){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(short){ "use strict"; }; true}); true is true
-PASS "use strict";/short/.test(function g(short){ "use strict"; }) is true
-PASS (function(){"use strict";/short/.test(function g(short){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(short){}; true is true
-PASS (function(){"use strict";try{}catch(short){}; true}); true is true
-PASS "use strict";function short(){ "use strict"; }; true is true
-PASS (function(){"use strict";function short(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "short": 42 }.short === 42) is true
-PASS (function(){"use strict";({ "short": 42 }.short === 42)}); true is true
-PASS "use strict";({ short: 42 }.short === 42) is true
-PASS (function(){"use strict";({ short: 42 }.short === 42)}); true is true
-PASS "use strict";({ get short(){}, set short(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get short(){}, set short(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var synchronized; true is true
-PASS (function(){var synchronized; true}); true is true
-PASS var synchronized = 42; synchronized === 42 is true
-PASS (function(){var synchronized = 42; synchronized === 42}); true is true
-PASS function g(synchronized){  }; true is true
-PASS (function(){function g(synchronized){  }; true}); true is true
-PASS /synchronized/.test(function g(synchronized){  }) is true
-PASS (function(){/synchronized/.test(function g(synchronized){  })}); true is true
-PASS try{}catch(synchronized){}; true is true
-PASS (function(){try{}catch(synchronized){}; true}); true is true
-PASS function synchronized(){  }; true is true
-PASS (function(){function synchronized(){  }; true}); true is true
-PASS ({ "synchronized": 42 }.synchronized === 42) is true
-PASS (function(){({ "synchronized": 42 }.synchronized === 42)}); true is true
-PASS ({ synchronized: 42 }.synchronized === 42) is true
-PASS (function(){({ synchronized: 42 }.synchronized === 42)}); true is true
-PASS ({ get synchronized(){}, set synchronized(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get synchronized(){}, set synchronized(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var synchronized; true is true
-PASS (function(){"use strict";var synchronized; true}); true is true
-PASS "use strict";var synchronized = 42; synchronized === 42 is true
-PASS (function(){"use strict";var synchronized = 42; synchronized === 42}); true is true
-PASS "use strict";function g(synchronized){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(synchronized){ "use strict"; }; true}); true is true
-PASS "use strict";/synchronized/.test(function g(synchronized){ "use strict"; }) is true
-PASS (function(){"use strict";/synchronized/.test(function g(synchronized){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(synchronized){}; true is true
-PASS (function(){"use strict";try{}catch(synchronized){}; true}); true is true
-PASS "use strict";function synchronized(){ "use strict"; }; true is true
-PASS (function(){"use strict";function synchronized(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "synchronized": 42 }.synchronized === 42) is true
-PASS (function(){"use strict";({ "synchronized": 42 }.synchronized === 42)}); true is true
-PASS "use strict";({ synchronized: 42 }.synchronized === 42) is true
-PASS (function(){"use strict";({ synchronized: 42 }.synchronized === 42)}); true is true
-PASS "use strict";({ get synchronized(){}, set synchronized(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get synchronized(){}, set synchronized(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var throws; true is true
-PASS (function(){var throws; true}); true is true
-PASS var throws = 42; throws === 42 is true
-PASS (function(){var throws = 42; throws === 42}); true is true
-PASS function g(throws){  }; true is true
-PASS (function(){function g(throws){  }; true}); true is true
-PASS /throws/.test(function g(throws){  }) is true
-PASS (function(){/throws/.test(function g(throws){  })}); true is true
-PASS try{}catch(throws){}; true is true
-PASS (function(){try{}catch(throws){}; true}); true is true
-PASS function throws(){  }; true is true
-PASS (function(){function throws(){  }; true}); true is true
-PASS ({ "throws": 42 }.throws === 42) is true
-PASS (function(){({ "throws": 42 }.throws === 42)}); true is true
-PASS ({ throws: 42 }.throws === 42) is true
-PASS (function(){({ throws: 42 }.throws === 42)}); true is true
-PASS ({ get throws(){}, set throws(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get throws(){}, set throws(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var throws; true is true
-PASS (function(){"use strict";var throws; true}); true is true
-PASS "use strict";var throws = 42; throws === 42 is true
-PASS (function(){"use strict";var throws = 42; throws === 42}); true is true
-PASS "use strict";function g(throws){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(throws){ "use strict"; }; true}); true is true
-PASS "use strict";/throws/.test(function g(throws){ "use strict"; }) is true
-PASS (function(){"use strict";/throws/.test(function g(throws){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(throws){}; true is true
-PASS (function(){"use strict";try{}catch(throws){}; true}); true is true
-PASS "use strict";function throws(){ "use strict"; }; true is true
-PASS (function(){"use strict";function throws(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "throws": 42 }.throws === 42) is true
-PASS (function(){"use strict";({ "throws": 42 }.throws === 42)}); true is true
-PASS "use strict";({ throws: 42 }.throws === 42) is true
-PASS (function(){"use strict";({ throws: 42 }.throws === 42)}); true is true
-PASS "use strict";({ get throws(){}, set throws(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get throws(){}, set throws(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var transient; true is true
-PASS (function(){var transient; true}); true is true
-PASS var transient = 42; transient === 42 is true
-PASS (function(){var transient = 42; transient === 42}); true is true
-PASS function g(transient){  }; true is true
-PASS (function(){function g(transient){  }; true}); true is true
-PASS /transient/.test(function g(transient){  }) is true
-PASS (function(){/transient/.test(function g(transient){  })}); true is true
-PASS try{}catch(transient){}; true is true
-PASS (function(){try{}catch(transient){}; true}); true is true
-PASS function transient(){  }; true is true
-PASS (function(){function transient(){  }; true}); true is true
-PASS ({ "transient": 42 }.transient === 42) is true
-PASS (function(){({ "transient": 42 }.transient === 42)}); true is true
-PASS ({ transient: 42 }.transient === 42) is true
-PASS (function(){({ transient: 42 }.transient === 42)}); true is true
-PASS ({ get transient(){}, set transient(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get transient(){}, set transient(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var transient; true is true
-PASS (function(){"use strict";var transient; true}); true is true
-PASS "use strict";var transient = 42; transient === 42 is true
-PASS (function(){"use strict";var transient = 42; transient === 42}); true is true
-PASS "use strict";function g(transient){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(transient){ "use strict"; }; true}); true is true
-PASS "use strict";/transient/.test(function g(transient){ "use strict"; }) is true
-PASS (function(){"use strict";/transient/.test(function g(transient){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(transient){}; true is true
-PASS (function(){"use strict";try{}catch(transient){}; true}); true is true
-PASS "use strict";function transient(){ "use strict"; }; true is true
-PASS (function(){"use strict";function transient(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "transient": 42 }.transient === 42) is true
-PASS (function(){"use strict";({ "transient": 42 }.transient === 42)}); true is true
-PASS "use strict";({ transient: 42 }.transient === 42) is true
-PASS (function(){"use strict";({ transient: 42 }.transient === 42)}); true is true
-PASS "use strict";({ get transient(){}, set transient(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get transient(){}, set transient(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS var volatile; true is true
-PASS (function(){var volatile; true}); true is true
-PASS var volatile = 42; volatile === 42 is true
-PASS (function(){var volatile = 42; volatile === 42}); true is true
-PASS function g(volatile){  }; true is true
-PASS (function(){function g(volatile){  }; true}); true is true
-PASS /volatile/.test(function g(volatile){  }) is true
-PASS (function(){/volatile/.test(function g(volatile){  })}); true is true
-PASS try{}catch(volatile){}; true is true
-PASS (function(){try{}catch(volatile){}; true}); true is true
-PASS function volatile(){  }; true is true
-PASS (function(){function volatile(){  }; true}); true is true
-PASS ({ "volatile": 42 }.volatile === 42) is true
-PASS (function(){({ "volatile": 42 }.volatile === 42)}); true is true
-PASS ({ volatile: 42 }.volatile === 42) is true
-PASS (function(){({ volatile: 42 }.volatile === 42)}); true is true
-PASS ({ get volatile(){}, set volatile(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){({ get volatile(){}, set volatile(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS "use strict";var volatile; true is true
-PASS (function(){"use strict";var volatile; true}); true is true
-PASS "use strict";var volatile = 42; volatile === 42 is true
-PASS (function(){"use strict";var volatile = 42; volatile === 42}); true is true
-PASS "use strict";function g(volatile){ "use strict"; }; true is true
-PASS (function(){"use strict";function g(volatile){ "use strict"; }; true}); true is true
-PASS "use strict";/volatile/.test(function g(volatile){ "use strict"; }) is true
-PASS (function(){"use strict";/volatile/.test(function g(volatile){ "use strict"; })}); true is true
-PASS "use strict";try{}catch(volatile){}; true is true
-PASS (function(){"use strict";try{}catch(volatile){}; true}); true is true
-PASS "use strict";function volatile(){ "use strict"; }; true is true
-PASS (function(){"use strict";function volatile(){ "use strict"; }; true}); true is true
-PASS "use strict";({ "volatile": 42 }.volatile === 42) is true
-PASS (function(){"use strict";({ "volatile": 42 }.volatile === 42)}); true is true
-PASS "use strict";({ volatile: 42 }.volatile === 42) is true
-PASS (function(){"use strict";({ volatile: 42 }.volatile === 42)}); true is true
-PASS "use strict";({ get volatile(){}, set volatile(_){}, parsedOkay: 42 }.parsedOkay === 42) is true
-PASS (function(){"use strict";({ get volatile(){}, set volatile(_){}, parsedOkay: 42 }.parsedOkay === 42)}); true is true
-PASS window.yield === 42 is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/js/reserved-words-as-property.html b/third_party/WebKit/LayoutTests/fast/js/reserved-words-as-property.html
deleted file mode 100644
index 3d4540a8..0000000
--- a/third_party/WebKit/LayoutTests/fast/js/reserved-words-as-property.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
-<script src="script-tests/reserved-words-as-property.js"></script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/js/script-tests/reserved-words-as-property.js b/third_party/WebKit/LayoutTests/fast/js/script-tests/reserved-words-as-property.js
deleted file mode 100644
index f86f3a1..0000000
--- a/third_party/WebKit/LayoutTests/fast/js/script-tests/reserved-words-as-property.js
+++ /dev/null
@@ -1,76 +0,0 @@
-description("Tests to ensure that we can use ES reserved words as property names.");
-
-var reservedWords = ["true", "false", "null", "break", "case", "catch", "continue", "debugger", "default", "delete", "do", "else", "finally", "for",
-                     "function", "if", "in", "instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with",
-                     "class", "const", "enum", "export", "extends", "import", "super"];
-
-var strictReservedWords = [
-    "implements",
-    "let",
-    "private",
-    "public",
-    "yield",
-    "interface",
-    "package",
-    "protected",
-    "static"
-];
-
-var unreservedWords = [
-    "abstract",
-    "boolean",
-    "byte",
-    "char",
-    "double",
-    "final",
-    "float",
-    "goto",
-    "int",
-    "long",
-    "native",
-    "short",
-    "synchronized",
-    "throws",
-    "transient",
-    "volatile"
-];
-
-
-function testWordEvalAndFunction(str, strShouldThrow) {
-    if (strShouldThrow) {
-        shouldThrow(str);
-        shouldThrow("(function(){"+str+"}); true");
-    } else {
-        shouldBeTrue(str);
-        shouldBeTrue("(function(){"+str+"}); true");
-    }
-}
-
-function testWord(word, strictPrefix, expectedResult) {
-    testWordEvalAndFunction(strictPrefix + "var " + word + "; true", expectedResult);
-    testWordEvalAndFunction(strictPrefix + "var " + word + " = 42; " + word + " === 42", expectedResult);
-    testWordEvalAndFunction(strictPrefix + "function g(" + word + "){ " + strictPrefix + " }; true", expectedResult);
-    testWordEvalAndFunction(strictPrefix + "/" + word + "/.test(function g(" + word + "){ " + strictPrefix + " })", expectedResult);
-    testWordEvalAndFunction(strictPrefix + "try{}catch(" + word + "){}; true", expectedResult);
-    testWordEvalAndFunction(strictPrefix + "function " + word + "(){ " + strictPrefix + " }; true", expectedResult);
-    // These should be allowed for all words, even reserved ones.
-    testWordEvalAndFunction(strictPrefix + "({ \"" + word + "\": 42 }." + word + " === 42)", false);
-    testWordEvalAndFunction(strictPrefix + "({ " + word + ": 42 }." + word + " === 42)", false);
-    testWordEvalAndFunction(strictPrefix + "({ get " + word + "(){}, set " + word + "(_){}, parsedOkay: 42 }.parsedOkay === 42)", false);
-}
-
-function testWordStrictAndNonStrict(word, condition) {
-    testWord(word, '', condition == "keyword");
-    testWord(word, '"use strict";', condition != "identifier");
-}
-
-for (var i = 0; i < reservedWords.length; i++)
-    testWordStrictAndNonStrict(reservedWords[i], "keyword");
-for (var i = 0; i < strictReservedWords.length; i++)
-    testWordStrictAndNonStrict(strictReservedWords[i], "strict");
-for (var i = 0; i < unreservedWords.length; i++)
-    testWordStrictAndNonStrict(unreservedWords[i], "identifier");
-
-// test access via window.
-var yield = 42;
-shouldBeTrue("window.yield === 42");
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/soft-break-before-first-child-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/soft-break-before-first-child-expected.txt
new file mode 100644
index 0000000..e970268
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/soft-break-before-first-child-expected.txt
@@ -0,0 +1,6 @@
+Test that the pagination strut isn't lost when it happens on the first block in a multicol container.
+
+There should be a blue square below.
+
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/soft-break-before-first-child.html b/third_party/WebKit/LayoutTests/fast/multicol/soft-break-before-first-child.html
new file mode 100644
index 0000000..f4ea654
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/soft-break-before-first-child.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script src="../../resources/check-layout.js"></script>
+<p>Test that the pagination strut isn't lost when it happens on the first block in a multicol container.</p>
+<p>There should be a blue square below.</p>
+<div id="multicol" style="position:relative; -webkit-columns:2; -webkit-column-gap:0; column-fill:auto; width:60px; height:40px; line-height:30px;">
+    <div data-offset-y="0" data-offset-x="30" style="margin-top:25px; background:blue;"><br></div>
+</div>
+<script>
+    checkLayout("#multicol");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/fixed-right-bottom-in-page-scale.html b/third_party/WebKit/LayoutTests/fast/repaint/fixed-right-bottom-in-page-scale.html
index 733d2de..4e5f178b 100644
--- a/third_party/WebKit/LayoutTests/fast/repaint/fixed-right-bottom-in-page-scale.html
+++ b/third_party/WebKit/LayoutTests/fast/repaint/fixed-right-bottom-in-page-scale.html
@@ -11,7 +11,8 @@
 
       function scroll() {
           // Fully scroll to bring the fixed pos rect into view.
-          window.scrollTo(500, 1700);
+          eventSender.mouseMoveTo(100, 100);
+          eventSender.continuousMouseScrollBy(-500, -1700);
       }
 
       function scaleWithEventSender() {
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/visual-viewport-scroll-no-onscroll-event-expected.txt b/third_party/WebKit/LayoutTests/fast/scroll-behavior/visual-viewport-scroll-no-onscroll-event-expected.txt
new file mode 100644
index 0000000..a54d795
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/visual-viewport-scroll-no-onscroll-event-expected.txt
@@ -0,0 +1,12 @@
+This test ensures that scrolling the visual viewport doesn't trigger an onscroll event.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+OnScroll called for scroll #1
+PASS numScrollsReceived is 1
+PASS numScrollsReceived is 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/visual-viewport-scroll-no-onscroll-event.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/visual-viewport-scroll-no-onscroll-event.html
new file mode 100644
index 0000000..341994f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/visual-viewport-scroll-no-onscroll-event.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<style>
+  #target {
+    width: 2000px;
+    height: 1500px;
+  }
+</style>
+<script>
+    var numScrollsReceived = 0;
+    var numRAFCalls = 0;
+    if (window.testRunner && window.internals) {
+        window.jsTestIsAsync = true;
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+        setPrintTestResultsLazily();
+    }
+
+    description("This test ensures that scrolling the visual viewport doesn't\
+        trigger an onscroll event.");
+
+    function runTest() {
+        if (!window.testRunner || !window.internals) {
+            testFailed("This test requires test runner and internals")
+            finishJSTest();
+            return;
+        }
+
+        window.internals.setPageScaleFactor(2.0);
+        var target = document.getElementById('target');
+
+        document.onscroll = function() {
+            ++numScrollsReceived;
+            debug('OnScroll called for scroll #' + numScrollsReceived);
+        }
+
+        var failureSentinel = function() {
+            if (numRAFCalls == 0) {
+                // The first scroll should trigger onscroll because it scrolls
+                // the layout viewport.
+                eventSender.mouseMoveTo(target.offsetLeft + 5, target.offsetTop + 5);
+                eventSender.continuousMouseScrollBy(0, -400);
+            } else if (numRAFCalls == 1) {
+                shouldBe('numScrollsReceived', '1');
+                // The second scroll should not trigger onscroll because it only
+                // scrolls the visual viewport.
+                eventSender.mouseMoveTo(target.offsetLeft + 5, target.offsetTop + 5);
+                eventSender.continuousMouseScrollBy(0, 40);
+            } else {
+                shouldBe('numScrollsReceived', '1');
+                finishJSTest();
+                return;
+            }
+            ++numRAFCalls;
+            window.requestAnimationFrame(failureSentinel);
+        }
+
+        window.requestAnimationFrame(failureSentinel);
+    }
+
+    onload = runTest;
+</script>
+<div id="target"></div>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
index 7791c0f..87ce97e28 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
@@ -92,7 +92,7 @@
         callback();
     }
     panel._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStarted, onRecordingStarted, this)
-    panel._enableJSSamplingSettingSetting.set(false);
+    panel._enableJSSamplingSetting.set(false);
     panel._toggleTimelineButton.element.click();
 };
 
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details-expected.txt
index 5f39859..803b5da 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details-expected.txt
@@ -319,3 +319,29 @@
         recursive_b: 0.008  0.008
           recursive_a: 0.008  0.008
 
+Events
+  a: 0.000  0.226
+    b: 0.000  0.226
+      c: 0.226  0.226
+  a: 0.000  8.155
+    b: 7.125  8.155
+      c: 0.125  0.125
+      e: 0.000  0.905
+        g: 0.905  0.905
+  f: 0.000  0.833
+    l: 0.000  0.833
+      a: 0.733  0.833
+        Layout: 0.100  0.100
+        Install Timer: 0.000  0.000
+  x: 0.000  1.513
+    y: 1.113  1.513
+      z: 0.000  0.200
+        w: 0.200  0.200
+      w: 0.200  0.200
+  recursive_a: 0.001  0.015
+    recursive_b: 0.002  0.014
+      recursive_a: 0.004  0.012
+        recursive_b: 0.008  0.008
+  recursive_a: 0.100  0.200
+    recursive_b: 0.100  0.100
+
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details.html
index 37c0a16..4d25022 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-aggregated-details.html
@@ -3,6 +3,10 @@
 <script src="../../http/tests/inspector/inspector-test.js"></script>
 <script src="../tracing-test.js"></script>
 <script>
+function initialize_EventsView()
+{
+    Runtime.experiments.enableForTest("timelineEventsTreeView");
+}
 
 function test()
 {
@@ -294,12 +298,29 @@
             }
         },
         "cat": "disabled-by-default-devtools.timeline",
+        "name": "TimerInstall",
+        "ph": "I",
+        "pid": 17851,
+        "tid": 23,
+        "ts": 230111
+    },
+    {
+        "args": {
+            "data": {
+                "stackTrace": [
+                    { "functionName": "a", "callUID": "a", "scriptId": 1 },
+                    { "functionName": "l", "callUID": "l", "scriptId": 1 },
+                    { "functionName": "f", "callUID": "f", "scriptId": 1 },
+                    { "functionName": "sin", "callUID": "sin", "scriptId": 2, "url": "native math.js" }
+                ]
+            }
+        },
+        "cat": "disabled-by-default-devtools.timeline",
         "name": "JSSample",
         "ph": "I",
         "pid": 17851,
         "tid": 23,
-        "ts": 230125,
-        "tts": 1758056
+        "ts": 230125
     },
     {
         "args": {},
@@ -560,32 +581,38 @@
         timeline.requestWindowTimes(0, Infinity);
         for (var grouping in WebInspector.AggregatedTimelineTreeView.GroupBy) {
             var groupingValue = WebInspector.AggregatedTimelineTreeView.GroupBy[grouping];
-            testProfileTree(WebInspector.TimelinePanel.DetailsTab.CallTree, groupingValue);
-            testProfileTree(WebInspector.TimelinePanel.DetailsTab.BottomUp, groupingValue);
+            testEventTree(WebInspector.TimelinePanel.DetailsTab.CallTree, groupingValue);
+            testEventTree(WebInspector.TimelinePanel.DetailsTab.BottomUp, groupingValue);
         }
+
+        testEventTree(WebInspector.TimelinePanel.DetailsTab.Events);
         InspectorTest.completeTest();
     }
 
-    function testProfileTree(type, grouping)
+    function testEventTree(type, grouping)
     {
         InspectorTest.addResult("");
-        InspectorTest.addResult(type + "  Group by: " + grouping);
         timeline._detailsView.selectTab(type, true);
         var callTree = timeline._detailsView._rangeDetailViews.get(type);
-        callTree._groupByCombobox.select(callTree._groupByCombobox.options().find((x) => x.value === grouping));
-        callTree._onGroupByChanged();
+        if (grouping) {
+            InspectorTest.addResult(type + "  Group by: " + grouping);
+            callTree._groupByCombobox.select(callTree._groupByCombobox.options().find((x) => x.value === grouping));
+            callTree._onGroupByChanged();
+        } else {
+            InspectorTest.addResult(type);
+        }
         var rootNode = callTree._dataGrid.rootNode();
         for (var node of rootNode.children)
-            printProfileTree(1, node._profileNode);
+            printEventTree(1, node._profileNode);
     }
 
-    function printProfileTree(padding, node)
+    function printEventTree(padding, node)
     {
         var name = node.name || (node.event.name === WebInspector.TimelineModel.RecordType.JSFrame
             ? WebInspector.beautifyFunctionName(node.event.args["data"]["functionName"])
             : WebInspector.TimelineUIUtils.eventTitle(node.event));
         InspectorTest.addResult("  ".repeat(padding) + name + ": " + [node.selfTime, node.totalTime].map(function (t) { return t.toFixed(3); }).join("  "));
-        (node.children || new Map()).forEach(printProfileTree.bind(null, padding + 1));
+        (node.children || new Map()).forEach(printEventTree.bind(null, padding + 1));
     }
 }
 
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1/coords-units-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
new file mode 100644
index 0000000..193487b3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/dom/length-list-parser-expected.txt b/third_party/WebKit/LayoutTests/platform/android/svg/dom/length-list-parser-expected.txt
new file mode 100644
index 0000000..18152a17
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/dom/length-list-parser-expected.txt
@@ -0,0 +1,326 @@
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e,-.e+968,52e,78-.,e809423-e7\t,8695e3"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0e-8"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 072"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="84e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t73+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="\u0000"
+This test fuzzes the length list parser with semi-random attribute values and dumps the results of any values that parse successfully.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Parsed as 1 length(s) [ 8.847 ]: 8.847
+Parsed as 1 length(s) [ 8.62569e+6 ]: 8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.	-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9	e 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 072
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/hixie/perf/006-expected.png b/third_party/WebKit/LayoutTests/platform/android/svg/hixie/perf/006-expected.png
new file mode 100644
index 0000000..a93b6f04
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/hixie/perf/006-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/android/svg/transforms/text-with-pattern-with-svg-transform-expected.png
new file mode 100644
index 0000000..8bbb39c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/transforms/text-with-pattern-with-svg-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux-precise/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/linux-precise/fast/html/details-writing-mode-expected.png
deleted file mode 100644
index dabea3c7..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux-precise/fast/html/details-writing-mode-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux-precise/fast/html/details-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/platform/linux-precise/fast/html/details-writing-mode-expected.txt
deleted file mode 100644
index 49a6a19..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux-precise/fast/html/details-writing-mode-expected.txt
+++ /dev/null
@@ -1,459 +0,0 @@
-layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 1508
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 785x1508 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
-  LayoutBlockFlow {HTML} at (0,0) size 785x1508
-    LayoutBlockFlow {BODY} at (8,8) size 769x1492
-      LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (163,6) size 151x19
-                text run at (163,6) width 151: "text-align not specified"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: left
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: down
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,358) size 769x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,378) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (191,6) size 95x19
-                text run at (191,6) width 95: "text-align: left"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 54x19
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: down
-                    LayoutText {#text} at (0,0) size 54x19
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: right
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,736) size 769x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,756) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (181,6) size 115x19
-                text run at (181,6) width 115: "text-align: center"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: right
-                    LayoutText {#text} at (41,0) size 55x19
-                      text run at (41,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: down
-                    LayoutText {#text} at (41,0) size 55x19
-                      text run at (41,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: down
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: right
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: down
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: left
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: left
-                    LayoutText {#text} at (24,0) size 55x19
-                      text run at (24,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: down
-                    LayoutText {#text} at (24,0) size 55x19
-                      text run at (24,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: up
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: right
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: up
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: left
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,1114) size 769x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,1134) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (187,6) size 103x19
-                text run at (187,6) width 103: "text-align: right"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: right
-                    LayoutText {#text} at (66,0) size 54x19
-                      text run at (66,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: down
-                    LayoutText {#text} at (66,0) size 54x19
-                      text run at (66,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: down
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: right
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: down
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: left
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: left
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: down
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/linux-x86/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/linux-x86/fast/html/details-writing-mode-expected.png
deleted file mode 100644
index d92c4922..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux-x86/fast/html/details-writing-mode-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux-x86/fast/html/details-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/platform/linux-x86/fast/html/details-writing-mode-expected.txt
deleted file mode 100644
index 73f7e6c..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux-x86/fast/html/details-writing-mode-expected.txt
+++ /dev/null
@@ -1,459 +0,0 @@
-layer at (0,0) size 800x600 scrollHeight 1508
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x1508 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x1508
-    LayoutBlockFlow {BODY} at (8,8) size 784x1492
-      LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (163,6) size 151x19
-                text run at (163,6) width 151: "text-align not specified"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: left
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: down
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,358) size 784x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,378) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (191,6) size 95x19
-                text run at (191,6) width 95: "text-align: left"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 54x19
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: down
-                    LayoutText {#text} at (0,0) size 54x19
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: right
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,736) size 784x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,756) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (181,6) size 115x19
-                text run at (181,6) width 115: "text-align: center"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: right
-                    LayoutText {#text} at (41,0) size 55x19
-                      text run at (41,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: down
-                    LayoutText {#text} at (41,0) size 55x19
-                      text run at (41,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: down
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: right
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: down
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: left
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: left
-                    LayoutText {#text} at (24,0) size 55x19
-                      text run at (24,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: down
-                    LayoutText {#text} at (24,0) size 55x19
-                      text run at (24,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: up
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: right
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: up
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: left
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,1114) size 784x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,1134) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (187,6) size 103x19
-                text run at (187,6) width 103: "text-align: right"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: right
-                    LayoutText {#text} at (66,0) size 54x19
-                      text run at (66,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: down
-                    LayoutText {#text} at (66,0) size 54x19
-                      text run at (66,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: down
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: right
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: down
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: left
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: left
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: down
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
deleted file mode 100644
index 3d219c84..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
deleted file mode 100644
index f87f98f..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x105
-  LayoutBlockFlow {HTML} at (0,0) size 800x105
-    LayoutBlockFlow {BODY} at (8,16) size 784x81
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 272x19
-          text run at (0,0) width 272: "crbug.com/322039: There should be a green "
-        LayoutInline {EM} at (0,0) size 43x19
-          LayoutText {#text} at (272,0) size 43x19
-            text run at (272,0) width 43: "square"
-        LayoutText {#text} at (314,0) size 438x19
-          text run at (314,0) width 438: " below. In the layout tree the float should be inside the anonymous block."
-      LayoutBlockFlow {DIV} at (0,36) size 150x45
-        LayoutBlockFlow {DIV} at (0,0) size 50x25 [bgcolor=#008000]
-        LayoutBlockFlow (anonymous) at (0,25) size 150x20
-          LayoutBlockFlow (floating) {DIV} at (0,0) size 50x25 [bgcolor=#008000]
-          LayoutText {#text} at (50,0) size 30x19
-            text run at (50,0) width 30: "Text."
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-center-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-center-expected.png
new file mode 100644
index 0000000..5d308bd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-center-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-center-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-center-expected.txt
new file mode 100644
index 0000000..c06291f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-center-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 481x356
+          LayoutTableRow {TR} at (0,2) size 481x32
+            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (181,6) size 115x19
+                text run at (181,6) width 115: "text-align: center"
+          LayoutTableRow {TR} at (0,36) size 481x32
+            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (47,6) size 5x19
+                text run at (47,6) width 5: " "
+            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (118,6) size 140x19
+                text run at (118,6) width 140: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,70) size 481x32
+            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (20,6) size 84x19
+                text run at (20,6) width 84: "horizontal-tb"
+            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-lr"
+            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-rl"
+          LayoutTableRow {TR} at (0,104) size 481x124
+            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 58x19
+                text run at (6,6) width 58: "direction"
+            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "ltr"
+            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: right
+                    LayoutText {#text} at (41,0) size 55x19
+                      text run at (41,0) width 55: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: down
+                    LayoutText {#text} at (41,0) size 55x19
+                      text run at (41,0) width 55: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: down
+                    LayoutText {#text} at (0,41) size 19x55
+                      text run at (0,41) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: right
+                    LayoutText {#text} at (0,41) size 19x55
+                      text run at (0,41) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: down
+                    LayoutText {#text} at (0,41) size 19x55
+                      text run at (0,41) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: left
+                    LayoutText {#text} at (0,41) size 19x55
+                      text run at (0,41) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+          LayoutTableRow {TR} at (0,230) size 481x124
+            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "rtl"
+            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: left
+                    LayoutText {#text} at (24,0) size 55x19
+                      text run at (24,0) width 55: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: down
+                    LayoutText {#text} at (24,0) size 55x19
+                      text run at (24,0) width 55: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: up
+                    LayoutText {#text} at (0,24) size 19x55
+                      text run at (0,24) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: right
+                    LayoutText {#text} at (0,24) size 19x55
+                      text run at (0,24) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: up
+                    LayoutText {#text} at (0,24) size 19x55
+                      text run at (0,24) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: left
+                    LayoutText {#text} at (0,24) size 19x55
+                      text run at (0,24) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-left-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-left-expected.png
new file mode 100644
index 0000000..17bcdc6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-left-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-left-expected.txt
new file mode 100644
index 0000000..e2029882
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-left-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 481x356
+          LayoutTableRow {TR} at (0,2) size 481x32
+            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (191,6) size 95x19
+                text run at (191,6) width 95: "text-align: left"
+          LayoutTableRow {TR} at (0,36) size 481x32
+            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (47,6) size 5x19
+                text run at (47,6) width 5: " "
+            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (118,6) size 140x19
+                text run at (118,6) width 140: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,70) size 481x32
+            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (20,6) size 84x19
+                text run at (20,6) width 84: "horizontal-tb"
+            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-lr"
+            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-rl"
+          LayoutTableRow {TR} at (0,104) size 481x124
+            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 58x19
+                text run at (6,6) width 58: "direction"
+            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "ltr"
+            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: right
+                    LayoutText {#text} at (16,0) size 55x19
+                      text run at (16,0) width 55: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: down
+                    LayoutText {#text} at (16,0) size 55x19
+                      text run at (16,0) width 55: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
+                    LayoutText {#text} at (0,16) size 19x55
+                      text run at (0,16) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
+                    LayoutText {#text} at (0,16) size 19x55
+                      text run at (0,16) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: down
+                    LayoutText {#text} at (0,16) size 19x55
+                      text run at (0,16) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: left
+                    LayoutText {#text} at (0,16) size 19x55
+                      text run at (0,16) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+          LayoutTableRow {TR} at (0,230) size 481x124
+            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "rtl"
+            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: left
+                    LayoutText {#text} at (0,0) size 54x19
+                      text run at (0,0) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: down
+                    LayoutText {#text} at (0,0) size 54x19
+                      text run at (0,0) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: up
+                    LayoutText {#text} at (0,0) size 19x54
+                      text run at (0,0) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: right
+                    LayoutText {#text} at (0,0) size 19x54
+                      text run at (0,0) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: up
+                    LayoutText {#text} at (0,0) size 19x54
+                      text run at (0,0) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: left
+                    LayoutText {#text} at (0,0) size 19x54
+                      text run at (0,0) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-right-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-right-expected.png
new file mode 100644
index 0000000..1f2e35ea
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-right-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-right-expected.txt
new file mode 100644
index 0000000..871500a2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-align-right-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 481x356
+          LayoutTableRow {TR} at (0,2) size 481x32
+            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (187,6) size 103x19
+                text run at (187,6) width 103: "text-align: right"
+          LayoutTableRow {TR} at (0,36) size 481x32
+            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (47,6) size 5x19
+                text run at (47,6) width 5: " "
+            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (118,6) size 140x19
+                text run at (118,6) width 140: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,70) size 481x32
+            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (20,6) size 84x19
+                text run at (20,6) width 84: "horizontal-tb"
+            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-lr"
+            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-rl"
+          LayoutTableRow {TR} at (0,104) size 481x124
+            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 58x19
+                text run at (6,6) width 58: "direction"
+            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "ltr"
+            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: right
+                    LayoutText {#text} at (66,0) size 54x19
+                      text run at (66,0) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: down
+                    LayoutText {#text} at (66,0) size 54x19
+                      text run at (66,0) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: down
+                    LayoutText {#text} at (0,66) size 19x54
+                      text run at (0,66) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: right
+                    LayoutText {#text} at (0,66) size 19x54
+                      text run at (0,66) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: down
+                    LayoutText {#text} at (0,66) size 19x54
+                      text run at (0,66) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: left
+                    LayoutText {#text} at (0,66) size 19x54
+                      text run at (0,66) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+          LayoutTableRow {TR} at (0,230) size 481x124
+            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "rtl"
+            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: left
+                    LayoutText {#text} at (49,0) size 55x19
+                      text run at (49,0) width 55: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: down
+                    LayoutText {#text} at (49,0) size 55x19
+                      text run at (49,0) width 55: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
+                    LayoutText {#text} at (0,49) size 19x55
+                      text run at (0,49) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
+                    LayoutText {#text} at (0,49) size 19x55
+                      text run at (0,49) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: up
+                    LayoutText {#text} at (0,49) size 19x55
+                      text run at (0,49) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: left
+                    LayoutText {#text} at (0,49) size 19x55
+                      text run at (0,49) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-expected.png
index d92c4922..afce3e0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-expected.txt
index 73f7e6c..1535aae3 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-writing-mode-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 scrollHeight 1508
+layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x1508 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x1508
-    LayoutBlockFlow {BODY} at (8,8) size 784x1492
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
         LayoutTableSection {TBODY} at (1,1) size 481x356
           LayoutTableRow {TR} at (0,2) size 481x32
@@ -115,345 +115,3 @@
                     LayoutText {#text} at (0,49) size 19x55
                       text run at (0,49) width 54: "summary"
                   LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,358) size 784x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,378) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (191,6) size 95x19
-                text run at (191,6) width 95: "text-align: left"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 54x19
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: down
-                    LayoutText {#text} at (0,0) size 54x19
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: right
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,736) size 784x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,756) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (181,6) size 115x19
-                text run at (181,6) width 115: "text-align: center"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: right
-                    LayoutText {#text} at (41,0) size 55x19
-                      text run at (41,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: down
-                    LayoutText {#text} at (41,0) size 55x19
-                      text run at (41,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: down
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: right
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: down
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: left
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: left
-                    LayoutText {#text} at (24,0) size 55x19
-                      text run at (24,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: down
-                    LayoutText {#text} at (24,0) size 55x19
-                      text run at (24,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: up
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: right
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: up
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: left
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,1114) size 784x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,1134) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (187,6) size 103x19
-                text run at (187,6) width 103: "text-align: right"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: right
-                    LayoutText {#text} at (66,0) size 54x19
-                      text run at (66,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: down
-                    LayoutText {#text} at (66,0) size 54x19
-                      text run at (66,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: down
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: right
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: down
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: left
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: left
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: down
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
index 193487b3..e83308c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/hixie/perf/006-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/hixie/perf/006-expected.png
index a93b6f04..7d9b7cd 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/hixie/perf/006-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/hixie/perf/006-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png
index 8bbb39c..bbf9fc80 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-lion/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/mac-lion/fast/html/details-writing-mode-expected.png
deleted file mode 100644
index 01941105..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-lion/fast/html/details-writing-mode-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/html/details-writing-mode-expected.png
deleted file mode 100644
index 342ddd81..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/html/details-writing-mode-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-writing-mode-expected.png
deleted file mode 100644
index 47b89dff..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-writing-mode-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-writing-mode-expected.txt
deleted file mode 100644
index 29cc4821..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-writing-mode-expected.txt
+++ /dev/null
@@ -1,459 +0,0 @@
-layer at (0,0) size 800x600 scrollHeight 1478
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x1478 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x1478
-    LayoutBlockFlow {BODY} at (8,8) size 784x1462
-      LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (164,6) size 155x18
-                text run at (164,6) width 155: "text-align not specified"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: left
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: down
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,352) size 784x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,370) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (193,6) size 97x18
-                text run at (193,6) width 97: "text-align: left"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 60x18
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: down
-                    LayoutText {#text} at (0,0) size 60x18
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,65.94) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,65.94) size 10.55x10.55: right
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,722) size 784x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,740) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (183,6) size 117x18
-                text run at (183,6) width 117: "text-align: center"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: right
-                    LayoutText {#text} at (38,0) size 61x18
-                      text run at (38,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: down
-                    LayoutText {#text} at (38,0) size 61x18
-                      text run at (38,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,21.75) size 10.55x10.55: down
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,21.75) size 10.55x10.55: right
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: down
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: left
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: left
-                    LayoutText {#text} at (21,0) size 61x18
-                      text run at (21,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: down
-                    LayoutText {#text} at (21,0) size 61x18
-                      text run at (21,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,87.69) size 10.55x10.55: up
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,87.69) size 10.55x10.55: right
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: up
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: left
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,1092) size 784x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,1110) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (187,6) size 109x18
-                text run at (187,6) width 109: "text-align: right"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: right
-                    LayoutText {#text} at (60,0) size 60x18
-                      text run at (60,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: down
-                    LayoutText {#text} at (60,0) size 60x18
-                      text run at (60,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,43.52) size 10.55x10.55: down
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,43.52) size 10.55x10.55: right
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: down
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: left
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: left
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: down
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/html/details-writing-mode-expected.png
deleted file mode 100644
index 47b89dff..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/html/details-writing-mode-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/html/details-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/html/details-writing-mode-expected.txt
deleted file mode 100644
index 29cc4821..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/html/details-writing-mode-expected.txt
+++ /dev/null
@@ -1,459 +0,0 @@
-layer at (0,0) size 800x600 scrollHeight 1478
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x1478 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x1478
-    LayoutBlockFlow {BODY} at (8,8) size 784x1462
-      LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (164,6) size 155x18
-                text run at (164,6) width 155: "text-align not specified"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: left
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: down
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,352) size 784x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,370) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (193,6) size 97x18
-                text run at (193,6) width 97: "text-align: left"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 60x18
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: down
-                    LayoutText {#text} at (0,0) size 60x18
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,65.94) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,65.94) size 10.55x10.55: right
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,722) size 784x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,740) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (183,6) size 117x18
-                text run at (183,6) width 117: "text-align: center"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: right
-                    LayoutText {#text} at (38,0) size 61x18
-                      text run at (38,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: down
-                    LayoutText {#text} at (38,0) size 61x18
-                      text run at (38,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,21.75) size 10.55x10.55: down
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,21.75) size 10.55x10.55: right
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: down
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: left
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: left
-                    LayoutText {#text} at (21,0) size 61x18
-                      text run at (21,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: down
-                    LayoutText {#text} at (21,0) size 61x18
-                      text run at (21,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,87.69) size 10.55x10.55: up
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,87.69) size 10.55x10.55: right
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: up
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: left
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,1092) size 784x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,1110) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (187,6) size 109x18
-                text run at (187,6) width 109: "text-align: right"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: right
-                    LayoutText {#text} at (60,0) size 60x18
-                      text run at (60,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: down
-                    LayoutText {#text} at (60,0) size 60x18
-                      text run at (60,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,43.52) size 10.55x10.55: down
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,43.52) size 10.55x10.55: right
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: down
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: left
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: left
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: down
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
deleted file mode 100644
index ec5a719..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
deleted file mode 100644
index d719a8df..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x119
-  LayoutBlockFlow {HTML} at (0,0) size 800x119
-    LayoutBlockFlow {BODY} at (8,16) size 784x95
-      LayoutBlockFlow {P} at (0,0) size 784x36
-        LayoutText {#text} at (0,0) size 287x18
-          text run at (0,0) width 287: "crbug.com/322039: There should be a green "
-        LayoutInline {EM} at (0,0) size 44x18
-          LayoutText {#text} at (286,0) size 44x18
-            text run at (286,0) width 44: "square"
-        LayoutText {#text} at (329,0) size 754x36
-          text run at (329,0) width 425: " below. In the layout tree the float should be inside the anonymous"
-          text run at (0,18) width 40: "block."
-      LayoutBlockFlow {DIV} at (0,52) size 150x43
-        LayoutBlockFlow {DIV} at (0,0) size 50x25 [bgcolor=#008000]
-        LayoutBlockFlow (anonymous) at (0,25) size 150x18
-          LayoutBlockFlow (floating) {DIV} at (0,0) size 50x25 [bgcolor=#008000]
-          LayoutText {#text} at (50,0) size 33x18
-            text run at (50,0) width 33: "Text."
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-center-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-center-expected.png
new file mode 100644
index 0000000..9a92b029
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-center-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-center-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-center-expected.txt
new file mode 100644
index 0000000..db07fa40
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-center-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 487x350
+          LayoutTableRow {TR} at (0,2) size 487x30
+            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (183,6) size 117x18
+                text run at (183,6) width 117: "text-align: center"
+          LayoutTableRow {TR} at (0,34) size 487x30
+            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (50,6) size 5x18
+                text run at (50,6) width 5: " "
+            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (113,6) size 150x18
+                text run at (113,6) width 150: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,66) size 487x30
+            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (17,6) size 90x18
+                text run at (17,6) width 90: "horizontal-tb"
+            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x18
+                text run at (27,6) width 70: "vertical-lr"
+            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x18
+                text run at (27,6) width 70: "vertical-rl"
+          LayoutTableRow {TR} at (0,98) size 487x124
+            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 62x18
+                text run at (6,6) width 62: "direction"
+            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x18
+                text run at (6,6) width 17: "ltr"
+            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: right
+                    LayoutText {#text} at (38,0) size 61x18
+                      text run at (38,0) width 61: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: down
+                    LayoutText {#text} at (38,0) size 61x18
+                      text run at (38,0) width 61: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,21.75) size 10.55x10.55: down
+                    LayoutText {#text} at (0,38) size 18x61
+                      text run at (0,38) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,21.75) size 10.55x10.55: right
+                    LayoutText {#text} at (0,38) size 18x61
+                      text run at (0,38) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: down
+                    LayoutText {#text} at (0,38) size 18x61
+                      text run at (0,38) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: left
+                    LayoutText {#text} at (0,38) size 18x61
+                      text run at (0,38) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+          LayoutTableRow {TR} at (0,224) size 487x124
+            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x18
+                text run at (6,6) width 17: "rtl"
+            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: left
+                    LayoutText {#text} at (21,0) size 61x18
+                      text run at (21,0) width 61: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: down
+                    LayoutText {#text} at (21,0) size 61x18
+                      text run at (21,0) width 61: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,87.69) size 10.55x10.55: up
+                    LayoutText {#text} at (0,21) size 18x61
+                      text run at (0,21) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,87.69) size 10.55x10.55: right
+                    LayoutText {#text} at (0,21) size 18x61
+                      text run at (0,21) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: up
+                    LayoutText {#text} at (0,21) size 18x61
+                      text run at (0,21) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: left
+                    LayoutText {#text} at (0,21) size 18x61
+                      text run at (0,21) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-left-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-left-expected.png
new file mode 100644
index 0000000..676ddf89
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-left-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-left-expected.txt
new file mode 100644
index 0000000..323c3c44
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-left-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 487x350
+          LayoutTableRow {TR} at (0,2) size 487x30
+            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (193,6) size 97x18
+                text run at (193,6) width 97: "text-align: left"
+          LayoutTableRow {TR} at (0,34) size 487x30
+            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (50,6) size 5x18
+                text run at (50,6) width 5: " "
+            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (113,6) size 150x18
+                text run at (113,6) width 150: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,66) size 487x30
+            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (17,6) size 90x18
+                text run at (17,6) width 90: "horizontal-tb"
+            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x18
+                text run at (27,6) width 70: "vertical-lr"
+            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x18
+                text run at (27,6) width 70: "vertical-rl"
+          LayoutTableRow {TR} at (0,98) size 487x124
+            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 62x18
+                text run at (6,6) width 62: "direction"
+            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x18
+                text run at (6,6) width 17: "ltr"
+            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: right
+                    LayoutText {#text} at (16,0) size 61x18
+                      text run at (16,0) width 61: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: down
+                    LayoutText {#text} at (16,0) size 61x18
+                      text run at (16,0) width 61: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
+                    LayoutText {#text} at (0,16) size 18x61
+                      text run at (0,16) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
+                    LayoutText {#text} at (0,16) size 18x61
+                      text run at (0,16) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: down
+                    LayoutText {#text} at (0,16) size 18x61
+                      text run at (0,16) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: left
+                    LayoutText {#text} at (0,16) size 18x61
+                      text run at (0,16) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+          LayoutTableRow {TR} at (0,224) size 487x124
+            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x18
+                text run at (6,6) width 17: "rtl"
+            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: left
+                    LayoutText {#text} at (0,0) size 60x18
+                      text run at (0,0) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: down
+                    LayoutText {#text} at (0,0) size 60x18
+                      text run at (0,0) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,65.94) size 10.55x10.55: up
+                    LayoutText {#text} at (0,0) size 18x60
+                      text run at (0,0) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,65.94) size 10.55x10.55: right
+                    LayoutText {#text} at (0,0) size 18x60
+                      text run at (0,0) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: up
+                    LayoutText {#text} at (0,0) size 18x60
+                      text run at (0,0) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: left
+                    LayoutText {#text} at (0,0) size 18x60
+                      text run at (0,0) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-right-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-right-expected.png
new file mode 100644
index 0000000..995791a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-right-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-right-expected.txt
new file mode 100644
index 0000000..c51be0a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-align-right-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 487x350
+          LayoutTableRow {TR} at (0,2) size 487x30
+            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (187,6) size 109x18
+                text run at (187,6) width 109: "text-align: right"
+          LayoutTableRow {TR} at (0,34) size 487x30
+            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (50,6) size 5x18
+                text run at (50,6) width 5: " "
+            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (113,6) size 150x18
+                text run at (113,6) width 150: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,66) size 487x30
+            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (17,6) size 90x18
+                text run at (17,6) width 90: "horizontal-tb"
+            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x18
+                text run at (27,6) width 70: "vertical-lr"
+            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x18
+                text run at (27,6) width 70: "vertical-rl"
+          LayoutTableRow {TR} at (0,98) size 487x124
+            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 62x18
+                text run at (6,6) width 62: "direction"
+            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x18
+                text run at (6,6) width 17: "ltr"
+            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: right
+                    LayoutText {#text} at (60,0) size 60x18
+                      text run at (60,0) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: down
+                    LayoutText {#text} at (60,0) size 60x18
+                      text run at (60,0) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,43.52) size 10.55x10.55: down
+                    LayoutText {#text} at (0,60) size 18x60
+                      text run at (0,60) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,43.52) size 10.55x10.55: right
+                    LayoutText {#text} at (0,60) size 18x60
+                      text run at (0,60) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: down
+                    LayoutText {#text} at (0,60) size 18x60
+                      text run at (0,60) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: left
+                    LayoutText {#text} at (0,60) size 18x60
+                      text run at (0,60) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+          LayoutTableRow {TR} at (0,224) size 487x124
+            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x18
+                text run at (6,6) width 17: "rtl"
+            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: left
+                    LayoutText {#text} at (43,0) size 61x18
+                      text run at (43,0) width 61: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: down
+                    LayoutText {#text} at (43,0) size 61x18
+                      text run at (43,0) width 61: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
+                    LayoutText {#text} at (0,43) size 18x61
+                      text run at (0,43) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
+                    LayoutText {#text} at (0,43) size 18x61
+                      text run at (0,43) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: up
+                    LayoutText {#text} at (0,43) size 18x61
+                      text run at (0,43) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: left
+                    LayoutText {#text} at (0,43) size 18x61
+                      text run at (0,43) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-expected.png
index 42bbb3e..b85dbbc6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-expected.txt
index 5d7d8b37a..ccd4b52 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/html/details-writing-mode-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 1478
+layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 785x1478 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
-  LayoutBlockFlow {HTML} at (0,0) size 785x1478
-    LayoutBlockFlow {BODY} at (8,8) size 769x1462
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
         LayoutTableSection {TBODY} at (1,1) size 487x350
           LayoutTableRow {TR} at (0,2) size 487x30
@@ -115,345 +115,3 @@
                     LayoutText {#text} at (0,43) size 18x61
                       text run at (0,43) width 60: "summary"
                   LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,352) size 769x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,370) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (193,6) size 97x18
-                text run at (193,6) width 97: "text-align: left"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 61x18
-                      text run at (16,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 18x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 60x18
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: down
-                    LayoutText {#text} at (0,0) size 60x18
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,65.94) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,65.94) size 10.55x10.55: right
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 18x60
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,722) size 769x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,740) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (183,6) size 117x18
-                text run at (183,6) width 117: "text-align: center"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: right
-                    LayoutText {#text} at (38,0) size 61x18
-                      text run at (38,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: down
-                    LayoutText {#text} at (38,0) size 61x18
-                      text run at (38,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,21.75) size 10.55x10.55: down
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,21.75) size 10.55x10.55: right
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: down
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: left
-                    LayoutText {#text} at (0,38) size 18x61
-                      text run at (0,38) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: left
-                    LayoutText {#text} at (21,0) size 61x18
-                      text run at (21,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: down
-                    LayoutText {#text} at (21,0) size 61x18
-                      text run at (21,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,87.69) size 10.55x10.55: up
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,87.69) size 10.55x10.55: right
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: up
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: left
-                    LayoutText {#text} at (0,21) size 18x61
-                      text run at (0,21) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,1092) size 769x18
-        LayoutBR {BR} at (0,0) size 0x18
-      LayoutTable {TABLE} at (0,1110) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (187,6) size 109x18
-                text run at (187,6) width 109: "text-align: right"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x18
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x18
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x18
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x18
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x18
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: right
-                    LayoutText {#text} at (60,0) size 60x18
-                      text run at (60,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: down
-                    LayoutText {#text} at (60,0) size 60x18
-                      text run at (60,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,43.52) size 10.55x10.55: down
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,43.52) size 10.55x10.55: right
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: down
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: left
-                    LayoutText {#text} at (0,60) size 18x60
-                      text run at (0,60) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x18
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: left
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: down
-                    LayoutText {#text} at (43,0) size 61x18
-                      text run at (43,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,43) size 18x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/gif-loop-count-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/images/gif-loop-count-expected.png
deleted file mode 100644
index 834bfddd..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/images/gif-loop-count-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/plugins/plugin-clip-subframe-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/plugins/plugin-clip-subframe-expected.txt
index 73b286f..e48932c0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/plugins/plugin-clip-subframe-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/plugins/plugin-clip-subframe-expected.txt
@@ -1,2 +1,2 @@
-CONSOLE MESSAGE: line 5: NPP_SetWindow: NULL window, Rect {0, 0, 300, 150}, Clip Rect {65518, 65318, 65518, 65318}, Type 2
+CONSOLE MESSAGE: line 5: NPP_SetWindow: NULL window, Rect {0, 0, 300, 150}, Clip Rect {65528, 65528, 65528, 65528}, Type 2
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
index c2f7d3a..a9b3408 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-02-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/hixie/perf/006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/hixie/perf/006-expected.png
index 672fa17..229c1bd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/hixie/perf/006-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/hixie/perf/006-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png
index 1c11395..48c9d1a3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
deleted file mode 100644
index 3eb21541..0000000
--- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
deleted file mode 100644
index 9d4b06f..0000000
--- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x105
-  LayoutBlockFlow {HTML} at (0,0) size 800x105
-    LayoutBlockFlow {BODY} at (8,16) size 784x81
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 272x19
-          text run at (0,0) width 272: "crbug.com/322039: There should be a green "
-        LayoutInline {EM} at (0,0) size 43x19
-          LayoutText {#text} at (272,0) size 43x19
-            text run at (272,0) width 43: "square"
-        LayoutText {#text} at (315,0) size 438x19
-          text run at (315,0) width 438: " below. In the layout tree the float should be inside the anonymous block."
-      LayoutBlockFlow {DIV} at (0,36) size 150x45
-        LayoutBlockFlow {DIV} at (0,0) size 50x25 [bgcolor=#008000]
-        LayoutBlockFlow (anonymous) at (0,25) size 150x20
-          LayoutBlockFlow (floating) {DIV} at (0,0) size 50x25 [bgcolor=#008000]
-          LayoutText {#text} at (50,0) size 31x19
-            text run at (50,0) width 31: "Text."
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-center-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-center-expected.png
new file mode 100644
index 0000000..454c3c8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-center-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-center-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-center-expected.txt
new file mode 100644
index 0000000..c06291f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-center-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 481x356
+          LayoutTableRow {TR} at (0,2) size 481x32
+            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (181,6) size 115x19
+                text run at (181,6) width 115: "text-align: center"
+          LayoutTableRow {TR} at (0,36) size 481x32
+            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (47,6) size 5x19
+                text run at (47,6) width 5: " "
+            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (118,6) size 140x19
+                text run at (118,6) width 140: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,70) size 481x32
+            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (20,6) size 84x19
+                text run at (20,6) width 84: "horizontal-tb"
+            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-lr"
+            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-rl"
+          LayoutTableRow {TR} at (0,104) size 481x124
+            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 58x19
+                text run at (6,6) width 58: "direction"
+            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "ltr"
+            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: right
+                    LayoutText {#text} at (41,0) size 55x19
+                      text run at (41,0) width 55: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: down
+                    LayoutText {#text} at (41,0) size 55x19
+                      text run at (41,0) width 55: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: down
+                    LayoutText {#text} at (0,41) size 19x55
+                      text run at (0,41) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: right
+                    LayoutText {#text} at (0,41) size 19x55
+                      text run at (0,41) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: down
+                    LayoutText {#text} at (0,41) size 19x55
+                      text run at (0,41) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: left
+                    LayoutText {#text} at (0,41) size 19x55
+                      text run at (0,41) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+          LayoutTableRow {TR} at (0,230) size 481x124
+            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "rtl"
+            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: left
+                    LayoutText {#text} at (24,0) size 55x19
+                      text run at (24,0) width 55: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: down
+                    LayoutText {#text} at (24,0) size 55x19
+                      text run at (24,0) width 55: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: up
+                    LayoutText {#text} at (0,24) size 19x55
+                      text run at (0,24) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: right
+                    LayoutText {#text} at (0,24) size 19x55
+                      text run at (0,24) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: up
+                    LayoutText {#text} at (0,24) size 19x55
+                      text run at (0,24) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: left
+                    LayoutText {#text} at (0,24) size 19x55
+                      text run at (0,24) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-left-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-left-expected.png
new file mode 100644
index 0000000..cc40549
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-left-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-left-expected.txt
new file mode 100644
index 0000000..e2029882
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-left-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 481x356
+          LayoutTableRow {TR} at (0,2) size 481x32
+            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (191,6) size 95x19
+                text run at (191,6) width 95: "text-align: left"
+          LayoutTableRow {TR} at (0,36) size 481x32
+            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (47,6) size 5x19
+                text run at (47,6) width 5: " "
+            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (118,6) size 140x19
+                text run at (118,6) width 140: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,70) size 481x32
+            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (20,6) size 84x19
+                text run at (20,6) width 84: "horizontal-tb"
+            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-lr"
+            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-rl"
+          LayoutTableRow {TR} at (0,104) size 481x124
+            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 58x19
+                text run at (6,6) width 58: "direction"
+            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "ltr"
+            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: right
+                    LayoutText {#text} at (16,0) size 55x19
+                      text run at (16,0) width 55: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: down
+                    LayoutText {#text} at (16,0) size 55x19
+                      text run at (16,0) width 55: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
+                    LayoutText {#text} at (0,16) size 19x55
+                      text run at (0,16) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
+                    LayoutText {#text} at (0,16) size 19x55
+                      text run at (0,16) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: down
+                    LayoutText {#text} at (0,16) size 19x55
+                      text run at (0,16) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: left
+                    LayoutText {#text} at (0,16) size 19x55
+                      text run at (0,16) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+          LayoutTableRow {TR} at (0,230) size 481x124
+            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "rtl"
+            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: left
+                    LayoutText {#text} at (0,0) size 54x19
+                      text run at (0,0) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: down
+                    LayoutText {#text} at (0,0) size 54x19
+                      text run at (0,0) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: up
+                    LayoutText {#text} at (0,0) size 19x54
+                      text run at (0,0) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: right
+                    LayoutText {#text} at (0,0) size 19x54
+                      text run at (0,0) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: up
+                    LayoutText {#text} at (0,0) size 19x54
+                      text run at (0,0) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: left
+                    LayoutText {#text} at (0,0) size 19x54
+                      text run at (0,0) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-right-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-right-expected.png
new file mode 100644
index 0000000..120ee2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-right-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-right-expected.txt
new file mode 100644
index 0000000..871500a2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-align-right-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 481x356
+          LayoutTableRow {TR} at (0,2) size 481x32
+            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (187,6) size 103x19
+                text run at (187,6) width 103: "text-align: right"
+          LayoutTableRow {TR} at (0,36) size 481x32
+            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (47,6) size 5x19
+                text run at (47,6) width 5: " "
+            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (118,6) size 140x19
+                text run at (118,6) width 140: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,70) size 481x32
+            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (20,6) size 84x19
+                text run at (20,6) width 84: "horizontal-tb"
+            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-lr"
+            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (29,6) size 66x19
+                text run at (29,6) width 66: "vertical-rl"
+          LayoutTableRow {TR} at (0,104) size 481x124
+            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 58x19
+                text run at (6,6) width 58: "direction"
+            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "ltr"
+            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: right
+                    LayoutText {#text} at (66,0) size 54x19
+                      text run at (66,0) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: down
+                    LayoutText {#text} at (66,0) size 54x19
+                      text run at (66,0) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: down
+                    LayoutText {#text} at (0,66) size 19x54
+                      text run at (0,66) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: right
+                    LayoutText {#text} at (0,66) size 19x54
+                      text run at (0,66) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: down
+                    LayoutText {#text} at (0,66) size 19x54
+                      text run at (0,66) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: left
+                    LayoutText {#text} at (0,66) size 19x54
+                      text run at (0,66) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+          LayoutTableRow {TR} at (0,230) size 481x124
+            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 15x19
+                text run at (6,6) width 15: "rtl"
+            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: left
+                    LayoutText {#text} at (49,0) size 55x19
+                      text run at (49,0) width 55: "summary"
+                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
+                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: down
+                    LayoutText {#text} at (49,0) size 55x19
+                      text run at (49,0) width 55: "summary"
+                  LayoutBlockFlow {DIV} at (0,20) size 120x0
+            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
+                    LayoutText {#text} at (0,49) size 19x55
+                      text run at (0,49) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
+                    LayoutText {#text} at (0,49) size 19x55
+                      text run at (0,49) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
+            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: up
+                    LayoutText {#text} at (0,49) size 19x55
+                      text run at (0,49) width 54: "summary"
+                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
+                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: left
+                    LayoutText {#text} at (0,49) size 19x55
+                      text run at (0,49) width 54: "summary"
+                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-expected.png
index a44c634..1c663f2 100644
--- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-expected.txt
index 49a6a19..1535aae3 100644
--- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/fast/html/details-writing-mode-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 1508
+layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 785x1508 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
-  LayoutBlockFlow {HTML} at (0,0) size 785x1508
-    LayoutBlockFlow {BODY} at (8,8) size 769x1492
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutTable {TABLE} at (0,0) size 483x358 [border: (1px outset #808080)]
         LayoutTableSection {TBODY} at (1,1) size 481x356
           LayoutTableRow {TR} at (0,2) size 481x32
@@ -115,345 +115,3 @@
                     LayoutText {#text} at (0,49) size 19x55
                       text run at (0,49) width 54: "summary"
                   LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,358) size 769x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,378) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (191,6) size 95x19
-                text run at (191,6) width 95: "text-align: left"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (0,5) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 55x19
-                      text run at (16,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 19x55
-                      text run at (0,16) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 54x19
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (60.39,5) size 10.55x10.55: down
-                    LayoutText {#text} at (0,0) size 54x19
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,60.39) size 10.55x10.55: right
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,60.39) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 19x54
-                      text run at (0,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,736) size 769x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,756) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (181,6) size 115x19
-                text run at (181,6) width 115: "text-align: center"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: right
-                    LayoutText {#text} at (41,0) size 55x19
-                      text run at (41,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (24.53,5) size 10.55x10.55: down
-                    LayoutText {#text} at (41,0) size 55x19
-                      text run at (41,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: down
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,24.53) size 10.55x10.55: right
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: down
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,24.53) size 10.55x10.55: left
-                    LayoutText {#text} at (0,41) size 19x55
-                      text run at (0,41) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: left
-                    LayoutText {#text} at (24,0) size 55x19
-                      text run at (24,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (84.92,5) size 10.55x10.55: down
-                    LayoutText {#text} at (24,0) size 55x19
-                      text run at (24,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: up
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,84.92) size 10.55x10.55: right
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: up
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,84.92) size 10.55x10.55: left
-                    LayoutText {#text} at (0,24) size 19x55
-                      text run at (0,24) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,1114) size 769x20
-        LayoutBR {BR} at (0,0) size 0x19
-      LayoutTable {TABLE} at (0,1134) size 483x358 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 481x356
-          LayoutTableRow {TR} at (0,2) size 481x32
-            LayoutTableCell {TH} at (2,2) size 477x32 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (187,6) size 103x19
-                text run at (187,6) width 103: "text-align: right"
-          LayoutTableRow {TR} at (0,36) size 481x32
-            LayoutTableCell {TH} at (2,53) size 99x32 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (47,6) size 5x19
-                text run at (47,6) width 5: " "
-            LayoutTableCell {TH} at (103,36) size 376x32 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (118,6) size 140x19
-                text run at (118,6) width 140: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,70) size 481x32
-            LayoutTableCell {TH} at (103,70) size 124x32 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (20,6) size 84x19
-                text run at (20,6) width 84: "horizontal-tb"
-            LayoutTableCell {TH} at (229,70) size 124x32 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-lr"
-            LayoutTableCell {TH} at (355,70) size 124x32 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (29,6) size 66x19
-                text run at (29,6) width 66: "vertical-rl"
-          LayoutTableRow {TR} at (0,104) size 481x124
-            LayoutTableCell {TH} at (2,213) size 70x32 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 58x19
-                text run at (6,6) width 58: "direction"
-            LayoutTableCell {TH} at (74,150) size 27x32 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "ltr"
-            LayoutTableCell {TD} at (103,104) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: right
-                    LayoutText {#text} at (66,0) size 54x19
-                      text run at (66,0) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (49.06,5) size 10.55x10.55: down
-                    LayoutText {#text} at (66,0) size 54x19
-                      text run at (66,0) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,104) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: down
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,49.06) size 10.55x10.55: right
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,104) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: down
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,49.06) size 10.55x10.55: left
-                    LayoutText {#text} at (0,66) size 19x54
-                      text run at (0,66) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-          LayoutTableRow {TR} at (0,230) size 481x124
-            LayoutTableCell {TH} at (74,276) size 27x32 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 15x19
-                text run at (6,6) width 15: "rtl"
-            LayoutTableCell {TD} at (103,230) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: left
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                LayoutBlockFlow {DETAILS} at (0,20) size 120x20
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x20
-                    LayoutDetailsMarker {DIV} at (109.45,5) size 10.55x10.55: down
-                    LayoutText {#text} at (49,0) size 55x19
-                      text run at (49,0) width 55: "summary"
-                  LayoutBlockFlow {DIV} at (0,20) size 120x0
-            LayoutTableCell {TD} at (229,230) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (3.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
-            LayoutTableCell {TD} at (355,230) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                LayoutBlockFlow {DETAILS} at (20,0) size 20x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 20x120
-                    LayoutDetailsMarker {DIV} at (5,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,49) size 19x55
-                      text run at (0,49) width 54: "summary"
-                  LayoutBlockFlow {DIV} at (20,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/svg/dom/length-list-parser-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/svg/dom/length-list-parser-expected.txt
new file mode 100644
index 0000000..18152a17
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win-xp/svg/dom/length-list-parser-expected.txt
@@ -0,0 +1,326 @@
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e,-.e+968,52e,78-.,e809423-e7\t,8695e3"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0e-8"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 072"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="84e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t73+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
+CONSOLE ERROR: Error: Invalid value for <text> attribute x="\u0000"
+This test fuzzes the length list parser with semi-random attribute values and dumps the results of any values that parse successfully.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Parsed as 1 length(s) [ 8.847 ]: 8.847
+Parsed as 1 length(s) [ 8.62569e+6 ]: 8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.	-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9	e 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 072
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
+Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
+Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
+Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
+Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
deleted file mode 100644
index 6f6cb0c..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
deleted file mode 100644
index 796b262..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/block/float/remove-div-after-float-and-before-anonymous-block-container-expected.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x119
-  LayoutBlockFlow {HTML} at (0,0) size 800x119
-    LayoutBlockFlow {BODY} at (8,16) size 784x95
-      LayoutBlockFlow {P} at (0,0) size 784x36
-        LayoutText {#text} at (0,0) size 287x17
-          text run at (0,0) width 287: "crbug.com/322039: There should be a green "
-        LayoutInline {EM} at (0,0) size 44x17
-          LayoutText {#text} at (286,0) size 44x17
-            text run at (286,0) width 44: "square"
-        LayoutText {#text} at (329,0) size 755x35
-          text run at (329,0) width 426: " below. In the layout tree the float should be inside the anonymous"
-          text run at (0,18) width 40: "block."
-      LayoutBlockFlow {DIV} at (0,52) size 150x43
-        LayoutBlockFlow {DIV} at (0,0) size 50x25 [bgcolor=#008000]
-        LayoutBlockFlow (anonymous) at (0,25) size 150x18
-          LayoutBlockFlow (floating) {DIV} at (0,0) size 50x25 [bgcolor=#008000]
-          LayoutText {#text} at (50,0) size 33x17
-            text run at (50,0) width 33: "Text."
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-center-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-center-expected.png
new file mode 100644
index 0000000..ce4ff305
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-center-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-center-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-center-expected.txt
new file mode 100644
index 0000000..10b5847a4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-center-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 487x350
+          LayoutTableRow {TR} at (0,2) size 487x30
+            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (183,6) size 117x17
+                text run at (183,6) width 117: "text-align: center"
+          LayoutTableRow {TR} at (0,34) size 487x30
+            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (50,6) size 5x17
+                text run at (50,6) width 5: " "
+            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (113,6) size 150x17
+                text run at (113,6) width 150: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,66) size 487x30
+            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (17,6) size 90x17
+                text run at (17,6) width 90: "horizontal-tb"
+            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x17
+                text run at (27,6) width 70: "vertical-lr"
+            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x17
+                text run at (27,6) width 70: "vertical-rl"
+          LayoutTableRow {TR} at (0,98) size 487x124
+            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 62x17
+                text run at (6,6) width 62: "direction"
+            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x17
+                text run at (6,6) width 17: "ltr"
+            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: right
+                    LayoutText {#text} at (38,0) size 61x17
+                      text run at (38,0) width 61: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: down
+                    LayoutText {#text} at (38,0) size 61x17
+                      text run at (38,0) width 61: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,21.75) size 10.55x10.55: down
+                    LayoutText {#text} at (0,38) size 17x61
+                      text run at (0,38) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,21.75) size 10.55x10.55: right
+                    LayoutText {#text} at (0,38) size 17x61
+                      text run at (0,38) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: down
+                    LayoutText {#text} at (0,38) size 17x61
+                      text run at (0,38) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: left
+                    LayoutText {#text} at (0,38) size 17x61
+                      text run at (0,38) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+          LayoutTableRow {TR} at (0,224) size 487x124
+            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x17
+                text run at (6,6) width 17: "rtl"
+            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: left
+                    LayoutText {#text} at (21,0) size 61x17
+                      text run at (21,0) width 61: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: down
+                    LayoutText {#text} at (21,0) size 61x17
+                      text run at (21,0) width 61: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,87.69) size 10.55x10.55: up
+                    LayoutText {#text} at (0,21) size 17x61
+                      text run at (0,21) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,87.69) size 10.55x10.55: right
+                    LayoutText {#text} at (0,21) size 17x61
+                      text run at (0,21) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: up
+                    LayoutText {#text} at (0,21) size 17x61
+                      text run at (0,21) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: left
+                    LayoutText {#text} at (0,21) size 17x61
+                      text run at (0,21) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-left-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-left-expected.png
new file mode 100644
index 0000000..bedbf645
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-left-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-left-expected.txt
new file mode 100644
index 0000000..f3f6d3c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-left-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 487x350
+          LayoutTableRow {TR} at (0,2) size 487x30
+            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (193,6) size 97x17
+                text run at (193,6) width 97: "text-align: left"
+          LayoutTableRow {TR} at (0,34) size 487x30
+            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (50,6) size 5x17
+                text run at (50,6) width 5: " "
+            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (113,6) size 150x17
+                text run at (113,6) width 150: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,66) size 487x30
+            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (17,6) size 90x17
+                text run at (17,6) width 90: "horizontal-tb"
+            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x17
+                text run at (27,6) width 70: "vertical-lr"
+            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x17
+                text run at (27,6) width 70: "vertical-rl"
+          LayoutTableRow {TR} at (0,98) size 487x124
+            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 62x17
+                text run at (6,6) width 62: "direction"
+            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x17
+                text run at (6,6) width 17: "ltr"
+            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: right
+                    LayoutText {#text} at (16,0) size 61x17
+                      text run at (16,0) width 61: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: down
+                    LayoutText {#text} at (16,0) size 61x17
+                      text run at (16,0) width 61: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,0) size 10.55x10.55: down
+                    LayoutText {#text} at (0,16) size 17x61
+                      text run at (0,16) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,0) size 10.55x10.55: right
+                    LayoutText {#text} at (0,16) size 17x61
+                      text run at (0,16) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: down
+                    LayoutText {#text} at (0,16) size 17x61
+                      text run at (0,16) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: left
+                    LayoutText {#text} at (0,16) size 17x61
+                      text run at (0,16) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+          LayoutTableRow {TR} at (0,224) size 487x124
+            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x17
+                text run at (6,6) width 17: "rtl"
+            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: left
+                    LayoutText {#text} at (0,0) size 60x17
+                      text run at (0,0) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: down
+                    LayoutText {#text} at (0,0) size 60x17
+                      text run at (0,0) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,65.94) size 10.55x10.55: up
+                    LayoutText {#text} at (0,0) size 17x60
+                      text run at (0,0) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,65.94) size 10.55x10.55: right
+                    LayoutText {#text} at (0,0) size 17x60
+                      text run at (0,0) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: up
+                    LayoutText {#text} at (0,0) size 17x60
+                      text run at (0,0) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: left
+                    LayoutText {#text} at (0,0) size 17x60
+                      text run at (0,0) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-right-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-right-expected.png
new file mode 100644
index 0000000..a3105f65
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-right-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-right-expected.txt
new file mode 100644
index 0000000..4d29585
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-align-right-expected.txt
@@ -0,0 +1,117 @@
+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
+      LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
+        LayoutTableSection {TBODY} at (1,1) size 487x350
+          LayoutTableRow {TR} at (0,2) size 487x30
+            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
+              LayoutText {#text} at (187,6) size 109x17
+                text run at (187,6) width 109: "text-align: right"
+          LayoutTableRow {TR} at (0,34) size 487x30
+            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
+              LayoutText {#text} at (50,6) size 5x17
+                text run at (50,6) width 5: " "
+            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
+              LayoutText {#text} at (113,6) size 150x17
+                text run at (113,6) width 150: "-webkit-writing-mode"
+          LayoutTableRow {TR} at (0,66) size 487x30
+            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (17,6) size 90x17
+                text run at (17,6) width 90: "horizontal-tb"
+            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x17
+                text run at (27,6) width 70: "vertical-lr"
+            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
+              LayoutText {#text} at (27,6) size 70x17
+                text run at (27,6) width 70: "vertical-rl"
+          LayoutTableRow {TR} at (0,98) size 487x124
+            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
+              LayoutText {#text} at (6,6) size 62x17
+                text run at (6,6) width 62: "direction"
+            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x17
+                text run at (6,6) width 17: "ltr"
+            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: right
+                    LayoutText {#text} at (60,0) size 60x17
+                      text run at (60,0) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: down
+                    LayoutText {#text} at (60,0) size 60x17
+                      text run at (60,0) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,43.52) size 10.55x10.55: down
+                    LayoutText {#text} at (0,60) size 17x60
+                      text run at (0,60) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,43.52) size 10.55x10.55: right
+                    LayoutText {#text} at (0,60) size 17x60
+                      text run at (0,60) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: down
+                    LayoutText {#text} at (0,60) size 17x60
+                      text run at (0,60) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: left
+                    LayoutText {#text} at (0,60) size 17x60
+                      text run at (0,60) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+          LayoutTableRow {TR} at (0,224) size 487x124
+            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 17x17
+                text run at (6,6) width 17: "rtl"
+            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: left
+                    LayoutText {#text} at (43,0) size 61x17
+                      text run at (43,0) width 61: "summary"
+                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
+                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: down
+                    LayoutText {#text} at (43,0) size 61x17
+                      text run at (43,0) width 61: "summary"
+                  LayoutBlockFlow {DIV} at (0,18) size 120x0
+            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,109.45) size 10.55x10.55: up
+                    LayoutText {#text} at (0,43) size 17x61
+                      text run at (0,43) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (2.45,109.45) size 10.55x10.55: right
+                    LayoutText {#text} at (0,43) size 17x61
+                      text run at (0,43) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
+            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
+              LayoutBlockFlow {DIV} at (2,2) size 120x120
+                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: up
+                    LayoutText {#text} at (0,43) size 17x61
+                      text run at (0,43) width 60: "summary"
+                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
+                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
+                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: left
+                    LayoutText {#text} at (0,43) size 17x61
+                      text run at (0,43) width 60: "summary"
+                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-expected.png
index 33e5df2..e124977 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-expected.txt
index e01e109..b3781686 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-writing-mode-expected.txt
@@ -1,8 +1,8 @@
-layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 1478
+layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 785x1478 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
-  LayoutBlockFlow {HTML} at (0,0) size 785x1478
-    LayoutBlockFlow {BODY} at (8,8) size 769x1462
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutTable {TABLE} at (0,0) size 489x352 [border: (1px outset #808080)]
         LayoutTableSection {TBODY} at (1,1) size 487x350
           LayoutTableRow {TR} at (0,2) size 487x30
@@ -115,345 +115,3 @@
                     LayoutText {#text} at (0,43) size 17x61
                       text run at (0,43) width 60: "summary"
                   LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,352) size 769x18
-        LayoutBR {BR} at (0,0) size 0x17
-      LayoutTable {TABLE} at (0,370) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (193,6) size 97x17
-                text run at (193,6) width 97: "text-align: left"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x17
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x17
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x17
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x17
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x17
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x17
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x17
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: right
-                    LayoutText {#text} at (16,0) size 61x17
-                      text run at (16,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (0,4) size 10.55x10.55: down
-                    LayoutText {#text} at (16,0) size 61x17
-                      text run at (16,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 17x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,0) size 10.55x10.55: right
-                    LayoutText {#text} at (0,16) size 17x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: down
-                    LayoutText {#text} at (0,16) size 17x61
-                      text run at (0,16) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,0) size 10.55x10.55: left
-                    LayoutText {#text} at (0,16) size 17x61
-                      text run at (0,16) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x17
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 60x17
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (65.94,4) size 10.55x10.55: down
-                    LayoutText {#text} at (0,0) size 60x17
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,65.94) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 17x60
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,65.94) size 10.55x10.55: right
-                    LayoutText {#text} at (0,0) size 17x60
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: up
-                    LayoutText {#text} at (0,0) size 17x60
-                      text run at (0,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,65.94) size 10.55x10.55: left
-                    LayoutText {#text} at (0,0) size 17x60
-                      text run at (0,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,722) size 769x18
-        LayoutBR {BR} at (0,0) size 0x17
-      LayoutTable {TABLE} at (0,740) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (183,6) size 117x17
-                text run at (183,6) width 117: "text-align: center"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x17
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x17
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x17
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x17
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x17
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x17
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x17
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: right
-                    LayoutText {#text} at (38,0) size 61x17
-                      text run at (38,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (21.75,4) size 10.55x10.55: down
-                    LayoutText {#text} at (38,0) size 61x17
-                      text run at (38,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,21.75) size 10.55x10.55: down
-                    LayoutText {#text} at (0,38) size 17x61
-                      text run at (0,38) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,21.75) size 10.55x10.55: right
-                    LayoutText {#text} at (0,38) size 17x61
-                      text run at (0,38) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: down
-                    LayoutText {#text} at (0,38) size 17x61
-                      text run at (0,38) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,21.75) size 10.55x10.55: left
-                    LayoutText {#text} at (0,38) size 17x61
-                      text run at (0,38) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x17
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: left
-                    LayoutText {#text} at (21,0) size 61x17
-                      text run at (21,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (87.69,4) size 10.55x10.55: down
-                    LayoutText {#text} at (21,0) size 61x17
-                      text run at (21,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,87.69) size 10.55x10.55: up
-                    LayoutText {#text} at (0,21) size 17x61
-                      text run at (0,21) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,87.69) size 10.55x10.55: right
-                    LayoutText {#text} at (0,21) size 17x61
-                      text run at (0,21) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: up
-                    LayoutText {#text} at (0,21) size 17x61
-                      text run at (0,21) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,87.69) size 10.55x10.55: left
-                    LayoutText {#text} at (0,21) size 17x61
-                      text run at (0,21) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-      LayoutBlockFlow (anonymous) at (0,1092) size 769x18
-        LayoutBR {BR} at (0,0) size 0x17
-      LayoutTable {TABLE} at (0,1110) size 489x352 [border: (1px outset #808080)]
-        LayoutTableSection {TBODY} at (1,1) size 487x350
-          LayoutTableRow {TR} at (0,2) size 487x30
-            LayoutTableCell {TH} at (2,2) size 483x30 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=5]
-              LayoutText {#text} at (187,6) size 109x17
-                text run at (187,6) width 109: "text-align: right"
-          LayoutTableRow {TR} at (0,34) size 487x30
-            LayoutTableCell {TH} at (2,50) size 105x30 [border: (1px inset #808080)] [r=1 c=0 rs=2 cs=2]
-              LayoutText {#text} at (50,6) size 5x17
-                text run at (50,6) width 5: " "
-            LayoutTableCell {TH} at (109,34) size 376x30 [border: (1px inset #808080)] [r=1 c=2 rs=1 cs=3]
-              LayoutText {#text} at (113,6) size 150x17
-                text run at (113,6) width 150: "-webkit-writing-mode"
-          LayoutTableRow {TR} at (0,66) size 487x30
-            LayoutTableCell {TH} at (109,66) size 124x30 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
-              LayoutText {#text} at (17,6) size 90x17
-                text run at (17,6) width 90: "horizontal-tb"
-            LayoutTableCell {TH} at (235,66) size 124x30 [border: (1px inset #808080)] [r=2 c=3 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x17
-                text run at (27,6) width 70: "vertical-lr"
-            LayoutTableCell {TH} at (361,66) size 124x30 [border: (1px inset #808080)] [r=2 c=4 rs=1 cs=1]
-              LayoutText {#text} at (27,6) size 70x17
-                text run at (27,6) width 70: "vertical-rl"
-          LayoutTableRow {TR} at (0,98) size 487x124
-            LayoutTableCell {TH} at (2,208) size 74x30 [border: (1px inset #808080)] [r=3 c=0 rs=4 cs=1]
-              LayoutText {#text} at (6,6) size 62x17
-                text run at (6,6) width 62: "direction"
-            LayoutTableCell {TH} at (78,145) size 29x30 [border: (1px inset #808080)] [r=3 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x17
-                text run at (6,6) width 17: "ltr"
-            LayoutTableCell {TD} at (109,98) size 124x124 [border: (1px solid #000000)] [r=3 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: right
-                    LayoutText {#text} at (60,0) size 60x17
-                      text run at (60,0) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (43.52,4) size 10.55x10.55: down
-                    LayoutText {#text} at (60,0) size 60x17
-                      text run at (60,0) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,98) size 124x124 [border: (1px solid #000000)] [r=3 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,43.52) size 10.55x10.55: down
-                    LayoutText {#text} at (0,60) size 17x60
-                      text run at (0,60) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,43.52) size 10.55x10.55: right
-                    LayoutText {#text} at (0,60) size 17x60
-                      text run at (0,60) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,98) size 124x124 [border: (1px solid #000000)] [r=3 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: down
-                    LayoutText {#text} at (0,60) size 17x60
-                      text run at (0,60) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,43.52) size 10.55x10.55: left
-                    LayoutText {#text} at (0,60) size 17x60
-                      text run at (0,60) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-          LayoutTableRow {TR} at (0,224) size 487x124
-            LayoutTableCell {TH} at (78,271) size 29x30 [border: (1px inset #808080)] [r=4 c=1 rs=1 cs=1]
-              LayoutText {#text} at (6,6) size 17x17
-                text run at (6,6) width 17: "rtl"
-            LayoutTableCell {TD} at (109,224) size 124x124 [border: (1px solid #000000)] [r=4 c=2 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: left
-                    LayoutText {#text} at (43,0) size 61x17
-                      text run at (43,0) width 61: "summary"
-                LayoutBlockFlow {DETAILS} at (0,18) size 120x18
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 120x18
-                    LayoutDetailsMarker {DIV} at (109.45,4) size 10.55x10.55: down
-                    LayoutText {#text} at (43,0) size 61x17
-                      text run at (43,0) width 61: "summary"
-                  LayoutBlockFlow {DIV} at (0,18) size 120x0
-            LayoutTableCell {TD} at (235,224) size 124x124 [border: (1px solid #000000)] [r=4 c=3 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 17x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (2.45,109.45) size 10.55x10.55: right
-                    LayoutText {#text} at (0,43) size 17x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
-            LayoutTableCell {TD} at (361,224) size 124x124 [border: (1px solid #000000)] [r=4 c=4 rs=1 cs=1]
-              LayoutBlockFlow {DIV} at (2,2) size 120x120
-                LayoutBlockFlow {DETAILS} at (0,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: up
-                    LayoutText {#text} at (0,43) size 17x61
-                      text run at (0,43) width 60: "summary"
-                LayoutBlockFlow {DETAILS} at (18,0) size 18x120
-                  LayoutBlockFlow {SUMMARY} at (0,0) size 18x120
-                    LayoutDetailsMarker {DIV} at (4,109.45) size 10.55x10.55: left
-                    LayoutText {#text} at (0,43) size 17x61
-                      text run at (0,43) width 60: "summary"
-                  LayoutBlockFlow {DIV} at (18,0) size 0x120
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/gif-loop-count-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/images/gif-loop-count-expected.png
deleted file mode 100644
index 6c82e3d9..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/images/gif-loop-count-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/hixie/perf/006-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/hixie/perf/006-expected.png
index 303ee057..2658f31 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/hixie/perf/006-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/hixie/perf/006-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png
index b7d0bf4..4e4cd7c0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/animations/svg-animation-parseValues.html b/third_party/WebKit/LayoutTests/svg/animations/svg-animation-parseValues.html
new file mode 100644
index 0000000..e61784bf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/animations/svg-animation-parseValues.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
+
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="tiny" id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
+  <g>
+    <animateTransform attributeName="transform" type="rotate" values="450;450;" dur="2s"/>
+    <rect fill="transparent" x="-20" y="-20" width="40" height="40"/>
+  </g>
+</svg>
+<script>
+var asyncHandle = async_test("Test for WebKit bug 12565. (parsing of animateTransform values). This test passes if it does not crash.");
+requestAnimationFrame(function() {
+  asyncHandle.done();
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/svg/dom/SVGLength-expected.txt b/third_party/WebKit/LayoutTests/svg/dom/SVGLength-expected.txt
index e6de085..aa7cf485 100644
--- a/third_party/WebKit/LayoutTests/svg/dom/SVGLength-expected.txt
+++ b/third_party/WebKit/LayoutTests/svg/dom/SVGLength-expected.txt
@@ -62,10 +62,10 @@
 PASS length.value is 2
 PASS length.valueInSpecifiedUnits is 2
 PASS length.unitType is SVGLength.SVG_LENGTHTYPE_PX
-PASS length.valueAsString = '1pX' threw exception SyntaxError: Failed to set the 'valueAsString' property on 'SVGLength': The value provided ('1pX') is invalid..
-PASS length.valueAsString is "2px"
-PASS length.value is 2
-PASS length.valueInSpecifiedUnits is 2
+PASS length.valueAsString = '1pX' did not throw exception.
+PASS length.valueAsString is "1px"
+PASS length.value is 1
+PASS length.valueInSpecifiedUnits is 1
 PASS length.unitType is SVGLength.SVG_LENGTHTYPE_PX
 PASS length.valueAsString = ',5 em' threw exception SyntaxError: Failed to set the 'valueAsString' property on 'SVGLength': The value provided (',5 em') is invalid..
 PASS length.valueAsString is "2px"
diff --git a/third_party/WebKit/LayoutTests/svg/dom/length-list-parser-expected.txt b/third_party/WebKit/LayoutTests/svg/dom/length-list-parser-expected.txt
index 18152a17..e7d157b5 100644
--- a/third_party/WebKit/LayoutTests/svg/dom/length-list-parser-expected.txt
+++ b/third_party/WebKit/LayoutTests/svg/dom/length-list-parser-expected.txt
@@ -239,84 +239,84 @@
 
 
 Parsed as 1 length(s) [ 8.847 ]: 8.847
-Parsed as 1 length(s) [ 8.62569e+6 ]: 8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.	-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9	e 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 072
+Parsed as 1 length(s) [ 8.62569e+06 ]: 8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.	-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9	e 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 072
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
 Parsed as 1 length(s) [ 1 ]: 1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-	8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198	50
 Parsed as 1 length(s) [ 564281 ]: 564281 0ee51+ e 	378584833	,.141	e8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010	8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-
-Parsed as 3 length(s) [ 0, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
-Parsed as 4 length(s) [ 4, 0, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
+Parsed as 3 length(s) [ -1.608e-146, 9, 367 ]: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608	9 367 ..81e9e539	e 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0
+Parsed as 4 length(s) [ 4, -1.993e-146, 35, 684 ]: 04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35	+684 +	159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960	1-9 289	
 Parsed as 1 length(s) [ 61822 ]: 61822,15-00.166.7 
 Parsed as 2 length(s) [ 2, 0.5 ]: 2	.5,658-7 e ,8477553
 Parsed as 3 length(s) [ 8, 2, 589 ]: 8 2 589	-45e58 -4	-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-	.765+-87 e. 68	9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1	+
diff --git a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGLength.js b/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGLength.js
index ba7663d1..01d8279 100644
--- a/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGLength.js
+++ b/third_party/WebKit/LayoutTests/svg/dom/script-tests/SVGLength.js
@@ -71,12 +71,14 @@
 shouldBe("length.valueInSpecifiedUnits", "2");
 shouldBe("length.unitType", "SVGLength.SVG_LENGTHTYPE_PX");
 
-shouldThrow("length.valueAsString = '1pX'");
-shouldBeEqualToString("length.valueAsString", "2px");
-shouldBe("length.value", "2");
-shouldBe("length.valueInSpecifiedUnits", "2");
+shouldNotThrow("length.valueAsString = '1pX'");
+shouldBeEqualToString("length.valueAsString", "1px");
+shouldBe("length.value", "1");
+shouldBe("length.valueInSpecifiedUnits", "1");
 shouldBe("length.unitType", "SVGLength.SVG_LENGTHTYPE_PX");
 
+length.valueAsString = "2px"; // reset to 2px
+
 shouldThrow("length.valueAsString = ',5 em'");
 shouldBeEqualToString("length.valueAsString", "2px");
 shouldBe("length.value", "2");
diff --git a/third_party/WebKit/LayoutTests/virtual/implsidepainting/inspector/tracing/frame-model-instrumentation-expected.txt b/third_party/WebKit/LayoutTests/virtual/implsidepainting/inspector/tracing/frame-model-instrumentation-expected.txt
deleted file mode 100644
index eea5ff95..0000000
--- a/third_party/WebKit/LayoutTests/virtual/implsidepainting/inspector/tracing/frame-model-instrumentation-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-layerTree: object
-mainFrameId: number
-paints: present
-
diff --git a/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-preventdefault-expected.txt b/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-preventdefault-expected.txt
index 1671b3b9..3bb27a3 100644
--- a/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-preventdefault-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/pointerevent/fast/events/pointerevents/mouse-pointer-preventdefault-expected.txt
@@ -16,18 +16,28 @@
 8. target received mousedown
 9. target received pointerup
 10. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 11. target received pointerdown
 12. target received mousedown
 13. target received pointermove
 14. target received mousemove
-15. target received pointerup
-16. target received mouseup
+15. target received pointerout
+16. target received mouseout
+17. target received pointerleave
+18. target received mouseleave
+19. target received pointerover
+20. target received mouseover
+21. target received pointerenter
+22. target received mouseenter
+23. target received pointermove
+24. target received mousemove
+25. target received pointerup
+26. target received mouseup
 - move outside target again -
-17. target received pointerout
-18. target received mouseout
-19. target received pointerleave
-20. target received mouseleave
+27. target received pointerout
+28. target received mouseout
+29. target received pointerleave
+30. target received mouseleave
 
 --- test with preventDefault on pointerdown ---
 - start with mouse outside target -
@@ -40,15 +50,24 @@
 6. target received mousemove
 7. target received pointerdown, prevented default
 8. target received pointerup
-- drag & release within target -
+- drag out of and into target & release within target -
 9. target received pointerdown, prevented default
 10. target received pointermove
-11. target received pointerup
+11. target received pointerout
+12. target received mouseout
+13. target received pointerleave
+14. target received mouseleave
+15. target received pointerover
+16. target received mouseover
+17. target received pointerenter
+18. target received mouseenter
+19. target received pointermove
+20. target received pointerup
 - move outside target again -
-12. target received pointerout
-13. target received mouseout
-14. target received pointerleave
-15. target received mouseleave
+21. target received pointerout
+22. target received mouseout
+23. target received pointerleave
+24. target received mouseleave
 
 --- test with preventDefault on pointerup ---
 - start with mouse outside target -
@@ -63,18 +82,28 @@
 8. target received mousedown
 9. target received pointerup, prevented default
 10. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 11. target received pointerdown
 12. target received mousedown
 13. target received pointermove
 14. target received mousemove
-15. target received pointerup, prevented default
-16. target received mouseup
+15. target received pointerout
+16. target received mouseout
+17. target received pointerleave
+18. target received mouseleave
+19. target received pointerover
+20. target received mouseover
+21. target received pointerenter
+22. target received mouseenter
+23. target received pointermove
+24. target received mousemove
+25. target received pointerup, prevented default
+26. target received mouseup
 - move outside target again -
-17. target received pointerout
-18. target received mouseout
-19. target received pointerleave
-20. target received mouseleave
+27. target received pointerout
+28. target received mouseout
+29. target received pointerleave
+30. target received mouseleave
 
 --- test with preventDefault on pointerenter ---
 - start with mouse outside target -
@@ -89,18 +118,28 @@
 8. target received mousedown
 9. target received pointerup
 10. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 11. target received pointerdown
 12. target received mousedown
 13. target received pointermove
 14. target received mousemove
-15. target received pointerup
-16. target received mouseup
+15. target received pointerout
+16. target received mouseout
+17. target received pointerleave
+18. target received mouseleave
+19. target received pointerover
+20. target received mouseover
+21. target received pointerenter, prevented default
+22. target received mouseenter
+23. target received pointermove
+24. target received mousemove
+25. target received pointerup
+26. target received mouseup
 - move outside target again -
-17. target received pointerout
-18. target received mouseout
-19. target received pointerleave
-20. target received mouseleave
+27. target received pointerout
+28. target received mouseout
+29. target received pointerleave
+30. target received mouseleave
 
 --- test with preventDefault on pointerleave ---
 - start with mouse outside target -
@@ -115,18 +154,28 @@
 8. target received mousedown
 9. target received pointerup
 10. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 11. target received pointerdown
 12. target received mousedown
 13. target received pointermove
 14. target received mousemove
-15. target received pointerup
-16. target received mouseup
+15. target received pointerout
+16. target received mouseout
+17. target received pointerleave, prevented default
+18. target received mouseleave
+19. target received pointerover
+20. target received mouseover
+21. target received pointerenter
+22. target received mouseenter
+23. target received pointermove
+24. target received mousemove
+25. target received pointerup
+26. target received mouseup
 - move outside target again -
-17. target received pointerout
-18. target received mouseout
-19. target received pointerleave, prevented default
-20. target received mouseleave
+27. target received pointerout
+28. target received mouseout
+29. target received pointerleave, prevented default
+30. target received mouseleave
 
 --- test with preventDefault on pointerover ---
 - start with mouse outside target -
@@ -141,18 +190,28 @@
 8. target received mousedown
 9. target received pointerup
 10. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 11. target received pointerdown
 12. target received mousedown
 13. target received pointermove
 14. target received mousemove
-15. target received pointerup
-16. target received mouseup
+15. target received pointerout
+16. target received mouseout
+17. target received pointerleave
+18. target received mouseleave
+19. target received pointerover, prevented default
+20. target received mouseover
+21. target received pointerenter
+22. target received mouseenter
+23. target received pointermove
+24. target received mousemove
+25. target received pointerup
+26. target received mouseup
 - move outside target again -
-17. target received pointerout
-18. target received mouseout
-19. target received pointerleave
-20. target received mouseleave
+27. target received pointerout
+28. target received mouseout
+29. target received pointerleave
+30. target received mouseleave
 
 --- test with preventDefault on pointerout ---
 - start with mouse outside target -
@@ -167,18 +226,28 @@
 8. target received mousedown
 9. target received pointerup
 10. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 11. target received pointerdown
 12. target received mousedown
 13. target received pointermove
 14. target received mousemove
-15. target received pointerup
-16. target received mouseup
+15. target received pointerout, prevented default
+16. target received mouseout
+17. target received pointerleave
+18. target received mouseleave
+19. target received pointerover
+20. target received mouseover
+21. target received pointerenter
+22. target received mouseenter
+23. target received pointermove
+24. target received mousemove
+25. target received pointerup
+26. target received mouseup
 - move outside target again -
-17. target received pointerout, prevented default
-18. target received mouseout
-19. target received pointerleave
-20. target received mouseleave
+27. target received pointerout, prevented default
+28. target received mouseout
+29. target received pointerleave
+30. target received mouseleave
 
 --- test with preventDefault on pointermove ---
 - start with mouse outside target -
@@ -193,18 +262,28 @@
 8. target received mousedown
 9. target received pointerup
 10. target received mouseup
-- drag & release within target -
+- drag out of and into target & release within target -
 11. target received pointerdown
 12. target received mousedown
 13. target received pointermove, prevented default
 14. target received mousemove
-15. target received pointerup
-16. target received mouseup
+15. target received pointerout
+16. target received mouseout
+17. target received pointerleave
+18. target received mouseleave
+19. target received pointerover
+20. target received mouseover
+21. target received pointerenter
+22. target received mouseenter
+23. target received pointermove, prevented default
+24. target received mousemove
+25. target received pointerup
+26. target received mouseup
 - move outside target again -
-17. target received pointerout
-18. target received mouseout
-19. target received pointerleave
-20. target received mouseleave
+27. target received pointerout
+28. target received mouseout
+29. target received pointerleave
+30. target received mouseleave
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/ManualTests/animation/animateTransform-parser.svg b/third_party/WebKit/ManualTests/animation/animateTransform-parser.svg
deleted file mode 100644
index 4e0dd72..0000000
--- a/third_party/WebKit/ManualTests/animation/animateTransform-parser.svg
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-animateTransform parsing code coverage for translate, rotate, skewX
-
-TODO: does not test e/E exponent notation
-
--->
-<svg xmlns="http://www.w3.org/2000/svg" width="800px" height="600px">
-	<g transform="translate(-90, -90)">
-		<circle fill="none" stroke="black" stroke-width="3" cx="200" cy="200" r="100" />
-		<line x1="200" y1="200" x2="300" y2="200" stroke="red" stroke-width="30" stroke-linecap="round">
-			<animateTransform attributeName="transform" type="rotate" from=" 0, 200, 200" to=" 360, 200, 200"
-				dur="5s" />
-		</line>
-		<line x1="200" y1="200" x2="300" y2="200" stroke="green" stroke-width="20" stroke-linecap="round">
-			<animateTransform attributeName="transform" type="rotate" from=" 0 200 200" to=" 360 200 200"
-				dur="5s" />
-		</line>
-		<line x1="200" y1="200" x2="300" y2="200" stroke="blue" stroke-width="10" stroke-linecap="round">
-			<animateTransform attributeName="transform" type="rotate" from=" 0,200,200" to=" 360,200,200"
-				dur="5s" />
-		</line>
-		<line x1="200" y1="200" x2="300" y2="200" stroke="white" stroke-width="5" stroke-linecap="round">
-			<animateTransform attributeName="transform" type="rotate" from=" 0,+200 +200" to=" 360 +200 +200"
-				dur="5s" />
-		</line>
-	</g>
-	<g transform="translate(300, 10)">
-		<rect fill="none" stroke="black" stroke-width="3" x="0" y="0" width="200" height="200" />
-		<circle fill="red" cx="0" cy="0" r="30">
-			<animateTransform attributeName="transform" type="translate" from="0, 0" to="200, 200" dur="5s" />
-		</circle>
-		<circle fill="green" cx="0" cy="0" r="20">
-			<animateTransform attributeName="transform" type="translate" from="0 0" to="200 200" dur="5s" />
-		</circle>
-		<circle fill="blue" cx="0" cy="0" r="10">
-			<animateTransform attributeName="transform" type="translate" from="0,0" to="200,200" dur="5s" />
-		</circle>
-		<circle fill="yellow" cx="0" cy="0" r="5">
-			<animateTransform attributeName="transform" type="translate" from=" +0,+0" to=" +200 +200" dur="5s" />
-		</circle>
-	</g>
-	<g transform="translate(10, 300)">
-		<rect fill="none" stroke="black" stroke-width="3" x="0" y="0" width="200" height="200" />
-		<rect fill="red" x="0" y="0" width="40" height="100">
-			<animateTransform attributeName="transform" type="scale" from="1,1" by="0,1" dur="5s" />
-		</rect>
-		<rect fill="green" x="0" y="0" width="30" height="100">
-			<animateTransform attributeName="transform" type="scale" from="1 1" by="0 1" dur="5s" />
-		</rect>
-		<rect fill="blue" x="0" y="0" width="20" height="100">
-			<animateTransform attributeName="transform" type="scale" from="1, 1" by="0, 1" dur="5s" />
-		</rect>
-		<rect fill="yellow" x="0" y="0" width="10" height="100">
-			<animateTransform attributeName="transform" type="scale" from="+1,+1" by=" +0, +1" dur="5s" />
-		</rect>
-
-		<rect fill="red" x="0" y="0" width="100" height="40">
-			<animateTransform attributeName="transform" type="scale" from="1,1" by="1,0" dur="5s" />
-		</rect>
-		<rect fill="green" x="0" y="0" width="100" height="30">
-			<animateTransform attributeName="transform" type="scale" from="1 1" by="1 0" dur="5s" />
-		</rect>
-		<rect fill="blue" x="0" y="0" width="100" height="20">
-			<animateTransform attributeName="transform" type="scale" from="1, 1" by="1, 0" dur="5s" />
-		</rect>
-		<rect fill="yellow" x="0" y="0" width="100" height="10">
-			<animateTransform attributeName="transform" type="scale" from="+1,+1" by=" +1, +0" dur="5s" />
-		</rect>
-	</g>
-
-	<g transform="translate(300, 300)">
-		<rect fill="none" stroke="black" stroke-width="3" x="0" y="0" width="200" height="200" />
-		<rect fill="red" x="0" y="0" width="100" height="100">
-			<animateTransform attributeName="transform" type="skewX" from="0" by="45" dur="5s" />
-		</rect>
-		<rect fill="green" x="0" y="0" width="50" height="100">
-			<animateTransform attributeName="transform" type="skewX" from="0" by=" 45" dur="5s" />
-		</rect>
-		<rect fill="blue" x="0" y="0" width="25" height="100">
-			<animateTransform attributeName="transform" type="skewX" from="0" by=" +45.0" dur="5s" />
-		</rect>
-	</g>
-</svg>
-
diff --git a/third_party/WebKit/ManualTests/svg-animation-parseValues.svg b/third_party/WebKit/ManualTests/svg-animation-parseValues.svg
deleted file mode 100644
index 391916cc..0000000
--- a/third_party/WebKit/ManualTests/svg-animation-parseValues.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
-
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="tiny" id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
-    <text text-anchor="middle" x="240" y="15" font-size="16">Test for WebKit bug 12565</text>
-    <text text-anchor="middle" x="240" y="35" font-size="16">(parsing of animateTransform values).</text>
-    <text text-anchor="middle" x="240" y="55" font-size="16">You should see a green square and no red.</text>
-    <g transform="translate(60,90)">
-        <rect fill="red" x="-19" y="-19" width="38" height="38"/>
-        <g fill="green">
-            <animateTransform attributeName="transform" type="rotate" values="450;450;" dur="1s"/>
-            <rect x="-20" y="-20" width="40" height="40"/>
-        </g>
-    </g>
-</svg>
diff --git a/third_party/WebKit/PRESUBMIT.py b/third_party/WebKit/PRESUBMIT.py
index 61a1efe1..435286e 100644
--- a/third_party/WebKit/PRESUBMIT.py
+++ b/third_party/WebKit/PRESUBMIT.py
@@ -96,7 +96,7 @@
 
 def _CheckTestExpectations(input_api, output_api):
     local_paths = [f.LocalPath() for f in input_api.AffectedFiles()]
-    if any(path.startswith('LayoutTests') for path in local_paths):
+    if any('LayoutTests' in path for path in local_paths):
         lint_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
             'Tools', 'Scripts', 'lint-test-expectations')
         _, errs = input_api.subprocess.Popen(
diff --git a/third_party/WebKit/PerformanceTests/Canvas/asyncPngImageEncoding.js b/third_party/WebKit/PerformanceTests/Canvas/asyncPngImageEncoding.js
new file mode 100644
index 0000000..d6831174b7
--- /dev/null
+++ b/third_party/WebKit/PerformanceTests/Canvas/asyncPngImageEncoding.js
@@ -0,0 +1,32 @@
+var isDone = false;
+
+function createCanvas4kBy4k(canvas_id) {
+    var myCanvas = document.createElement("canvas");
+    myCanvas.id = canvas_id;
+    myCanvas.width = 4000;
+    myCanvas.height = 4000;
+    myCanvas.getContext("2d").fillStyle = 'green';
+    myCanvas.getContext("2d").fillRect(0, 0, myCanvas.width, myCanvas.height);
+    return myCanvas;
+}
+
+function invokeToBlobPng(myCanvas) {
+    var startTime = PerfTestRunner.now();
+    myCanvas.toBlob(function(blob){
+        PerfTestRunner.measureValueAsync(PerfTestRunner.now() - startTime);
+        if (!isDone) {
+            PerfTestRunner.gc();
+            runTest(myCanvas);
+        }
+    });
+}
+
+function draw() {
+    if (!isDone)
+        requestAnimationFrame(draw);
+}
+
+function runTest(myCanvas) {
+    draw(); //repeatedly draw the frame to keep main thread busy
+    invokeToBlobPng(myCanvas);
+}
diff --git a/third_party/WebKit/PerformanceTests/Canvas/idlePngImageEncoding.html b/third_party/WebKit/PerformanceTests/Canvas/idlePngImageEncoding.html
new file mode 100644
index 0000000..1862cb2e
--- /dev/null
+++ b/third_party/WebKit/PerformanceTests/Canvas/idlePngImageEncoding.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src = "../resources/runner.js"></script>
+<script src = "./asyncPngImageEncoding.js"></script>
+<script>
+
+var canvas_idle = null;
+
+window.onload = function () {
+    window.internals.settings.setIdleCanvasImageEncodingEnabled(true);
+    canvas_idle = createCanvas4kBy4k("canvas_idle");
+    PerfTestRunner.prepareToMeasureValuesAsync({
+        unit: 'ms',
+        done: function () {
+            isDone = true;
+        },
+        description: "Measures performance of canvas." + 
+            "toBlob that has png image encoding performed in idle periods."
+    });
+    runTest(canvas_idle);
+};
+</script>
+</body>
+</html>
+
diff --git a/third_party/WebKit/PerformanceTests/Canvas/threadedPngImageEncoding.html b/third_party/WebKit/PerformanceTests/Canvas/threadedPngImageEncoding.html
new file mode 100644
index 0000000..a362ef4
--- /dev/null
+++ b/third_party/WebKit/PerformanceTests/Canvas/threadedPngImageEncoding.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src = "../resources/runner.js"></script>
+<script src = "./asyncPngImageEncoding.js"></script>
+<script>
+
+var canvas_threaded = null;
+
+window.onload = function () {
+    window.internals.settings.setIdleCanvasImageEncodingEnabled(false);
+    canvas_threaded = createCanvas4kBy4k("canvas_threaded");
+    PerfTestRunner.prepareToMeasureValuesAsync({
+        unit: 'ms',
+        done: function () {
+            isDone = true;
+        },
+        description: "Measures performance of canvas." + 
+            "toBlob that has png image encoding performed on a separate thread."
+    });
+    runTest(canvas_threaded);
+};
+</script>
+</body>
+</html>
+
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8GCForContextDispose.cpp b/third_party/WebKit/Source/bindings/core/v8/V8GCForContextDispose.cpp
index 1683547..d9d723566 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8GCForContextDispose.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8GCForContextDispose.cpp
@@ -70,7 +70,7 @@
 
 void V8GCForContextDispose::pseudoIdleTimerFired(Timer<V8GCForContextDispose>*)
 {
-    V8PerIsolateData::mainThreadIsolate()->IdleNotificationDeadline(Platform::current()->monotonicallyIncreasingTime());
+    V8PerIsolateData::mainThreadIsolate()->IdleNotificationDeadline(Platform::current()->monotonicallyIncreasingTimeSeconds());
     reset();
 }
 
diff --git a/third_party/WebKit/Source/core/animation/LengthSVGInterpolation.cpp b/third_party/WebKit/Source/core/animation/LengthSVGInterpolation.cpp
index f051dfa..2207525 100644
--- a/third_party/WebKit/Source/core/animation/LengthSVGInterpolation.cpp
+++ b/third_party/WebKit/Source/core/animation/LengthSVGInterpolation.cpp
@@ -60,43 +60,52 @@
     LengthInterpolatedCHS,
 };
 
-static const SVGLengthType unitTypes[] = { LengthTypeNumber, LengthTypePercentage, LengthTypeEMS, LengthTypeEXS, LengthTypeREMS, LengthTypeCHS };
+static const CSSPrimitiveValue::UnitType unitTypes[] = {
+    CSSPrimitiveValue::UnitType::Number,
+    CSSPrimitiveValue::UnitType::Percentage,
+    CSSPrimitiveValue::UnitType::Ems,
+    CSSPrimitiveValue::UnitType::Exs,
+    CSSPrimitiveValue::UnitType::Rems,
+    CSSPrimitiveValue::UnitType::Chs
+};
 
 const size_t numLengthInterpolatedUnits = WTF_ARRAY_LENGTH(unitTypes);
 
-LengthInterpolatedUnit convertToInterpolatedUnit(SVGLengthType lengthType, double& value)
+LengthInterpolatedUnit convertToInterpolatedUnit(CSSPrimitiveValue::UnitType unitType, double& value)
 {
-    switch (lengthType) {
-    case LengthTypeUnknown:
+    switch (unitType) {
+    case CSSPrimitiveValue::UnitType::Unknown:
     default:
         ASSERT_NOT_REACHED();
-    case LengthTypePX:
-    case LengthTypeNumber:
+    case CSSPrimitiveValue::UnitType::Pixels:
+    case CSSPrimitiveValue::UnitType::Number:
         return LengthInterpolatedNumber;
-    case LengthTypePercentage:
+    case CSSPrimitiveValue::UnitType::Percentage:
         return LengthInterpolatedPercentage;
-    case LengthTypeEMS:
+    case CSSPrimitiveValue::UnitType::Ems:
         return LengthInterpolatedEMS;
-    case LengthTypeEXS:
+    case CSSPrimitiveValue::UnitType::Exs:
         return LengthInterpolatedEXS;
-    case LengthTypeCM:
+    case CSSPrimitiveValue::UnitType::Centimeters:
         value *= cssPixelsPerCentimeter;
         return LengthInterpolatedNumber;
-    case LengthTypeMM:
+    case CSSPrimitiveValue::UnitType::Millimeters:
         value *= cssPixelsPerMillimeter;
         return LengthInterpolatedNumber;
-    case LengthTypeIN:
+    case CSSPrimitiveValue::UnitType::Inches:
         value *= cssPixelsPerInch;
         return LengthInterpolatedNumber;
-    case LengthTypePT:
+    case CSSPrimitiveValue::UnitType::Points:
         value *= cssPixelsPerPoint;
         return LengthInterpolatedNumber;
-    case LengthTypePC:
+    case CSSPrimitiveValue::UnitType::Picas:
         value *= cssPixelsPerPica;
         return LengthInterpolatedNumber;
-    case LengthTypeREMS:
+    case CSSPrimitiveValue::UnitType::UserUnits:
+        return LengthInterpolatedNumber;
+    case CSSPrimitiveValue::UnitType::Rems:
         return LengthInterpolatedREMS;
-    case LengthTypeCHS:
+    case CSSPrimitiveValue::UnitType::Chs:
         return LengthInterpolatedCHS;
     }
 }
@@ -109,7 +118,7 @@
         populateModeData(attribute, ptrModeData);
 
     double value = length->valueInSpecifiedUnits();
-    LengthInterpolatedUnit unitType = convertToInterpolatedUnit(length->unitType(), value);
+    LengthInterpolatedUnit unitType = convertToInterpolatedUnit(length->typeWithCalcResolved(), value);
 
     double values[numLengthInterpolatedUnits] = { };
     values[unitType] = value;
@@ -126,7 +135,7 @@
     ASSERT(element);
 
     double value = 0;
-    SVGLengthType lengthType = LengthTypeNumber;
+    CSSPrimitiveValue::UnitType unitType = CSSPrimitiveValue::UnitType::UserUnits;
     unsigned unitTypeCount = 0;
     // We optimise for the common case where only one unit type is involved.
     for (size_t i = 0; i < numLengthInterpolatedUnits; i++) {
@@ -138,12 +147,12 @@
             break;
 
         value = entry;
-        lengthType = unitTypes[i];
+        unitType = unitTypes[i];
     }
 
     if (unitTypeCount > 1) {
         value = 0;
-        lengthType = LengthTypeNumber;
+        unitType = CSSPrimitiveValue::UnitType::UserUnits;
 
         // SVGLength does not support calc expressions, so we convert to canonical units.
         SVGLengthContext lengthContext(element);
@@ -158,8 +167,7 @@
         value = 0;
 
     RefPtrWillBeRawPtr<SVGLength> result = SVGLength::create(modeData.unitMode); // defaults to the length 0
-    result->setUnitType(lengthType);
-    result->setValueInSpecifiedUnits(value);
+    result->newValueSpecifiedUnits(unitType, value);
     return result.release();
 }
 
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
index 5355f56..3699bc78 100644
--- a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
+++ b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
@@ -543,7 +543,7 @@
 
 PassOwnPtr<Keyframe::PropertySpecificKeyframe> SVGPropertySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const
 {
-    return adoptPtr(new SVGPropertySpecificKeyframe(offset, easing, "", EffectModel::CompositeAdd));
+    return adoptPtr(new SVGPropertySpecificKeyframe(offset, easing, String(), EffectModel::CompositeAdd));
 }
 
 namespace {
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp b/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
index d3b2d53..23fa5ca7 100644
--- a/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
+++ b/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
@@ -365,7 +365,7 @@
         return AnimatableShadow::create(style.boxShadow(), style.color());
     case CSSPropertyClip:
         if (style.hasAutoClip())
-            return AnimatableUnknown::create(CSSPrimitiveValue::create(CSSValueAuto));
+            return AnimatableUnknown::create(CSSPrimitiveValue::createIdentifier(CSSValueAuto));
         return createFromLengthBox(style.clip(), style);
     case CSSPropertyColor:
         return createFromColor(property, style);
diff --git a/third_party/WebKit/Source/core/css/CSSBasicShapeValues.cpp b/third_party/WebKit/Source/core/css/CSSBasicShapeValues.cpp
index f291e29..6ae78c29 100644
--- a/third_party/WebKit/Source/core/css/CSSBasicShapeValues.cpp
+++ b/third_party/WebKit/Source/core/css/CSSBasicShapeValues.cpp
@@ -100,7 +100,7 @@
         side = defaultSide;
     }
 
-    return CSSValuePair::create(cssValuePool().createValue(side), amount.release(), CSSValuePair::KeepIdenticalValues);
+    return CSSValuePair::create(cssValuePool().createIdentifierValue(side), amount.release(), CSSValuePair::KeepIdenticalValues);
 }
 
 String CSSBasicShapeCircleValue::customCSSText() const
diff --git a/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp b/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
index 28bf1abd..34375ad8 100644
--- a/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
@@ -63,6 +63,7 @@
     case CSSPrimitiveValue::UnitType::Inches:
     case CSSPrimitiveValue::UnitType::Points:
     case CSSPrimitiveValue::UnitType::Picas:
+    case CSSPrimitiveValue::UnitType::UserUnits:
     case CSSPrimitiveValue::UnitType::Rems:
     case CSSPrimitiveValue::UnitType::Chs:
     case CSSPrimitiveValue::UnitType::ViewportWidth:
@@ -101,6 +102,7 @@
     case CSSPrimitiveValue::UnitType::Inches:
     case CSSPrimitiveValue::UnitType::Points:
     case CSSPrimitiveValue::UnitType::Picas:
+    case CSSPrimitiveValue::UnitType::UserUnits:
     case CSSPrimitiveValue::UnitType::Degrees:
     case CSSPrimitiveValue::UnitType::Radians:
     case CSSPrimitiveValue::UnitType::Gradians:
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp b/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp
index e879977..d364936 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp
@@ -60,6 +60,7 @@
     table.set(String("in"), CSSPrimitiveValue::UnitType::Inches);
     table.set(String("pt"), CSSPrimitiveValue::UnitType::Points);
     table.set(String("pc"), CSSPrimitiveValue::UnitType::Picas);
+    table.set(String(""), CSSPrimitiveValue::UnitType::UserUnits);
     table.set(String("deg"), CSSPrimitiveValue::UnitType::Degrees);
     table.set(String("rad"), CSSPrimitiveValue::UnitType::Radians);
     table.set(String("grad"), CSSPrimitiveValue::UnitType::Gradians);
@@ -120,6 +121,7 @@
     case UnitType::Inches:
     case UnitType::Points:
     case UnitType::Picas:
+    case UnitType::UserUnits:
         return CSSPrimitiveValue::ULength;
     case UnitType::Milliseconds:
     case UnitType::Seconds:
@@ -328,6 +330,7 @@
     case UnitType::Inches:
     case UnitType::Points:
     case UnitType::Picas:
+    case UnitType::UserUnits:
     case UnitType::Degrees:
     case UnitType::Radians:
     case UnitType::Gradians:
@@ -459,6 +462,7 @@
     switch (unitType) {
     // These are "canonical" units in their respective categories.
     case UnitType::Pixels:
+    case UnitType::UserUnits:
     case UnitType::Degrees:
     case UnitType::Milliseconds:
     case UnitType::Hertz:
@@ -646,6 +650,7 @@
     switch (type) {
     case UnitType::Number:
     case UnitType::Integer:
+    case UnitType::UserUnits:
         return "";
     case UnitType::Percentage:
         return "%";
@@ -744,6 +749,7 @@
     case UnitType::Inches:
     case UnitType::Points:
     case UnitType::Picas:
+    case UnitType::UserUnits:
     case UnitType::Degrees:
     case UnitType::Radians:
     case UnitType::Gradians:
@@ -800,6 +806,7 @@
     case UnitType::Inches:
     case UnitType::Points:
     case UnitType::Picas:
+    case UnitType::UserUnits:
     case UnitType::Degrees:
     case UnitType::Radians:
     case UnitType::Gradians:
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h
index df7447c..ad4009ca 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h
@@ -30,6 +30,7 @@
 #include "wtf/Forward.h"
 #include "wtf/MathExtras.h"
 #include "wtf/PassRefPtr.h"
+#include "wtf/TypeTraits.h"
 #include "wtf/text/StringHash.h"
 
 namespace blink {
@@ -76,6 +77,7 @@
         Inches,
         Points,
         Picas,
+        UserUnits, // The SVG term for unitless lengths
         Degrees,
         Radians,
         Gradians,
@@ -167,7 +169,7 @@
     static bool isViewportPercentageLength(UnitType type) { return type >= UnitType::ViewportWidth && type <= UnitType::ViewportMax; }
     static bool isLength(UnitType type)
     {
-        return (type >= UnitType::Ems && type <= UnitType::Picas) || type == UnitType::QuirkyEms || type == UnitType::Rems || type == UnitType::Chs || isViewportPercentageLength(type);
+        return (type >= UnitType::Ems && type <= UnitType::UserUnits) || type == UnitType::QuirkyEms || type == UnitType::Rems || type == UnitType::Chs || isViewportPercentageLength(type);
     }
     bool isLength() const { return isLength(typeWithCalcResolved()); }
     bool isNumber() const { return typeWithCalcResolved() == UnitType::Number || typeWithCalcResolved() == UnitType::Integer; }
@@ -199,6 +201,7 @@
     }
     template<typename T> static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(T value)
     {
+        static_assert(!WTF::IsSameType<T, CSSValueID>::value, "Do not call create() with a CSSValueID; call createIdentifier() instead");
         return adoptRefWillBeNoop(new CSSPrimitiveValue(value));
     }
 
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index b4b5809c..a10c3c2 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -55,26 +55,12 @@
 
 namespace blink {
 
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(short i)
-    : CSSValue(PrimitiveClass)
-{
-    init(UnitType::Number);
-    m_value.num = static_cast<double>(i);
-}
-
 template<> inline short CSSPrimitiveValue::convertTo() const
 {
     ASSERT(isNumber());
     return clampTo<short>(getDoubleValue());
 }
 
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(unsigned short i)
-    : CSSValue(PrimitiveClass)
-{
-    init(UnitType::Number);
-    m_value.num = static_cast<double>(i);
-}
-
 template<> inline unsigned short CSSPrimitiveValue::convertTo() const
 {
     ASSERT(isNumber());
@@ -93,14 +79,6 @@
     return clampTo<unsigned>(getDoubleValue());
 }
 
-
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(float i)
-    : CSSValue(PrimitiveClass)
-{
-    init(UnitType::Number);
-    m_value.num = static_cast<double>(i);
-}
-
 template<> inline float CSSPrimitiveValue::convertTo() const
 {
     ASSERT(isNumber());
@@ -208,7 +186,7 @@
 template<> inline ColumnSpan CSSPrimitiveValue::convertTo() const
 {
     // Map 1 to none for compatibility reasons.
-    if (type() == UnitType::Number && m_value.num == 1)
+    if (type() == UnitType::Integer && m_value.num == 1)
         return ColumnSpanNone;
 
     ASSERT(isValueID());
diff --git a/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp b/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
index 38613f8..e34b3a6 100644
--- a/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
+++ b/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
@@ -122,6 +122,7 @@
     // zoomedComputedPixels() more generic (to solve both cases) without hurting performance.
     switch (type) {
     case CSSPrimitiveValue::UnitType::Pixels:
+    case CSSPrimitiveValue::UnitType::UserUnits:
         return value * zoom();
 
     case CSSPrimitiveValue::UnitType::Centimeters:
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 93ce3b2..8f17a4de 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -150,9 +150,9 @@
 {
     switch (type) {
     case MaskAlpha:
-        return cssValuePool().createValue(CSSValueAlpha);
+        return cssValuePool().createIdentifierValue(CSSValueAlpha);
     case MaskLuminance:
-        return cssValuePool().createValue(CSSValueLuminance);
+        return cssValuePool().createIdentifierValue(CSSValueLuminance);
     }
 
     ASSERT_NOT_REACHED();
@@ -1186,7 +1186,7 @@
         RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
         values->append(CSSURIValue::create(url));
         if (paintType == SVG_PAINTTYPE_URI_NONE)
-            values->append(CSSPrimitiveValue::create(CSSValueNone));
+            values->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
         else if (paintType == SVG_PAINTTYPE_URI_CURRENTCOLOR)
             values->append(CSSColorValue::create(currentColor.rgb()));
         else if (paintType == SVG_PAINTTYPE_URI_RGBCOLOR)
@@ -1194,7 +1194,7 @@
         return values.release();
     }
     if (paintType == SVG_PAINTTYPE_NONE)
-        return CSSPrimitiveValue::create(CSSValueNone);
+        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
     if (paintType == SVG_PAINTTYPE_CURRENTCOLOR)
         return CSSColorValue::create(currentColor.rgb());
 
@@ -1598,9 +1598,9 @@
     case CSSPropertyFlexFlow:
         return valuesForShorthandProperty(flexFlowShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
     case CSSPropertyFlexGrow:
-        return cssValuePool().createValue(style.flexGrow());
+        return cssValuePool().createValue(style.flexGrow(), CSSPrimitiveValue::UnitType::Number);
     case CSSPropertyFlexShrink:
-        return cssValuePool().createValue(style.flexShrink());
+        return cssValuePool().createValue(style.flexShrink(), CSSPrimitiveValue::UnitType::Number);
     case CSSPropertyFlexWrap:
         return cssValuePool().createValue(style.flexWrap());
     case CSSPropertyJustifyContent:
@@ -1736,7 +1736,7 @@
         return CSSPrimitiveValue::create(style.imageRendering());
     case CSSPropertyImageOrientation:
         if (style.respectImageOrientation() == RespectImageOrientation)
-            return cssValuePool().createValue(CSSValueFromImage);
+            return cssValuePool().createIdentifierValue(CSSValueFromImage);
         return cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Degrees);
     case CSSPropertyIsolation:
         return cssValuePool().createValue(style.isolation());
diff --git a/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp b/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp
index 0797d01b..7fd97faf 100644
--- a/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp
+++ b/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp
@@ -152,7 +152,7 @@
 
         // If the rule has no properties to apply, then ignore it in the non-debug mode.
         const StylePropertySet& properties = rule->properties();
-        if (properties.isEmpty() && !matchRequest.includeEmptyRules)
+        if (properties.isEmpty() && !m_includeEmptyRules)
             continue;
 
         SelectorChecker::MatchResult result;
diff --git a/third_party/WebKit/Source/core/css/MediaValues.cpp b/third_party/WebKit/Source/core/css/MediaValues.cpp
index 3fb45985..294df98 100644
--- a/third_party/WebKit/Source/core/css/MediaValues.cpp
+++ b/third_party/WebKit/Source/core/css/MediaValues.cpp
@@ -167,6 +167,7 @@
         factor = defaultFontSize;
         break;
     case CSSPrimitiveValue::UnitType::Pixels:
+    case CSSPrimitiveValue::UnitType::UserUnits:
         factor = 1;
         break;
     case CSSPrimitiveValue::UnitType::Exs:
diff --git a/third_party/WebKit/Source/core/css/MediaValuesTest.cpp b/third_party/WebKit/Source/core/css/MediaValuesTest.cpp
index 70f70d8..096fa01 100644
--- a/third_party/WebKit/Source/core/css/MediaValuesTest.cpp
+++ b/third_party/WebKit/Source/core/css/MediaValuesTest.cpp
@@ -39,6 +39,7 @@
         { 1.3, CSSPrimitiveValue::UnitType::Inches, 16, 300, 300, true, 124 },
         { 13, CSSPrimitiveValue::UnitType::Points, 16, 300, 300, true, 17 },
         { 1.3, CSSPrimitiveValue::UnitType::Picas, 16, 300, 300, true, 20 },
+        { 40.0, CSSPrimitiveValue::UnitType::UserUnits, 16, 300, 300, true, 40 },
         { 1.3, CSSPrimitiveValue::UnitType::Unknown, 16, 300, 300, false, 20 },
         { 0.0, CSSPrimitiveValue::UnitType::Unknown, 0, 0, 0, false, 0.0 } // Do not remove the terminating line.
     };
diff --git a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
index b40d7b9..eb8165d 100644
--- a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
+++ b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
@@ -815,7 +815,7 @@
 static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue& repeatXCSSValue, const CSSValue& repeatYCSSValue)
 {
     // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS.
-    DEFINE_STATIC_REF_WILL_BE_PERSISTENT(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValue::create(CSSValueRepeat)));
+    DEFINE_STATIC_REF_WILL_BE_PERSISTENT(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValue::createIdentifier(CSSValueRepeat)));
     const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() ? *initialRepeatValue : toCSSPrimitiveValue(repeatXCSSValue);
     const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() ? *initialRepeatValue : toCSSPrimitiveValue(repeatYCSSValue);
     CSSValueID repeatXValueId = repeatX.getValueID();
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
index 3b00467..f84f25d4 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
@@ -110,9 +110,13 @@
 
     if (unit == CSSPrimitiveValue::UnitType::Number) {
         bool quirksMode = isQuirksModeBehavior(cssParserMode);
-        if (number && !quirksMode)
+        bool svgMode = cssParserMode == SVGAttributeMode;
+        if (number && (!quirksMode && !svgMode))
             return nullptr;
-        unit = CSSPrimitiveValue::UnitType::Pixels;
+        if (svgMode)
+            unit = CSSPrimitiveValue::UnitType::UserUnits;
+        else
+            unit = CSSPrimitiveValue::UnitType::Pixels;
     }
     if (number < 0 && !acceptsNegativeNumbers)
         return nullptr;
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index c950d18c..bcc8ea01 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -11,6 +11,7 @@
 #include "core/css/CSSFontFaceSrcValue.h"
 #include "core/css/CSSFontFeatureValue.h"
 #include "core/css/CSSFunctionValue.h"
+#include "core/css/CSSPathValue.h"
 #include "core/css/CSSPrimitiveValueMappings.h"
 #include "core/css/CSSQuadValue.h"
 #include "core/css/CSSSVGDocumentValue.h"
@@ -26,6 +27,7 @@
 #include "core/css/parser/CSSParserValues.h"
 #include "core/frame/UseCounter.h"
 #include "core/layout/LayoutTheme.h"
+#include "core/svg/SVGPathUtilities.h"
 #include "wtf/text/StringBuilder.h"
 
 namespace blink {
@@ -278,6 +280,7 @@
         case CSSPrimitiveValue::UnitType::Inches:
         case CSSPrimitiveValue::UnitType::Points:
         case CSSPrimitiveValue::UnitType::Picas:
+        case CSSPrimitiveValue::UnitType::UserUnits:
         case CSSPrimitiveValue::UnitType::ViewportWidth:
         case CSSPrimitiveValue::UnitType::ViewportHeight:
         case CSSPrimitiveValue::UnitType::ViewportMin:
@@ -294,7 +297,10 @@
         if (!shouldAcceptUnitlessValues(token.numericValue(), cssParserMode, unitless)
             || (valueRange == ValueRangeNonNegative && token.numericValue() < 0))
             return nullptr;
-        return cssValuePool().createValue(range.consumeIncludingWhitespace().numericValue(), CSSPrimitiveValue::UnitType::Pixels);
+        CSSPrimitiveValue::UnitType unitType = CSSPrimitiveValue::UnitType::Pixels;
+        if (cssParserMode == SVGAttributeMode)
+            unitType = CSSPrimitiveValue::UnitType::UserUnits;
+        return cssValuePool().createValue(range.consumeIncludingWhitespace().numericValue(), unitType);
     }
     CalcParser calcParser(range, valueRange);
     if (calcParser.value() && calcParser.value()->category() == CalcLength)
@@ -1422,7 +1428,7 @@
     return shadowValueList;
 }
 
-static PassRefPtrWillBeRawPtr<CSSFunctionValue> consumeFilterFunction(CSSParserTokenRange& range,  const CSSParserContext& context)
+static PassRefPtrWillBeRawPtr<CSSFunctionValue> consumeFilterFunction(CSSParserTokenRange& range, const CSSParserContext& context)
 {
     CSSValueID filterType = range.peek().functionId();
     if (filterType < CSSValueInvert || filterType > CSSValueDropShadow)
@@ -1464,7 +1470,7 @@
     return filterValue.release();
 }
 
-static PassRefPtrWillBeRawPtr<CSSValue> consumeFilter(CSSParserTokenRange& range,  const CSSParserContext& context)
+static PassRefPtrWillBeRawPtr<CSSValue> consumeFilter(CSSParserTokenRange& range, const CSSParserContext& context)
 {
     if (range.peek().id() == CSSValueNone)
         return consumeIdent(range);
@@ -1505,21 +1511,47 @@
     return list.release();
 }
 
-static PassRefPtrWillBeRawPtr<CSSValue> consumeOutlineColor(CSSParserTokenRange& range, const CSSParserContext& context)
-{
-    // Outline color has "invert" as additional keyword.
-    // Also, we want to allow the special focus color even in HTML Standard parsing mode.
-    if (range.peek().id() == CSSValueInvert || range.peek().id() == CSSValueWebkitFocusRingColor)
-        return consumeIdent(range);
-    return consumeColor(range, context);
-}
-
-static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeLineWidth(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+static PassRefPtrWillBeRawPtr<CSSValue> consumeMotionPath(CSSParserTokenRange& range)
 {
     CSSValueID id = range.peek().id();
-    if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick)
+    if (id == CSSValueNone)
         return consumeIdent(range);
-    return consumeLength(range, cssParserMode, ValueRangeNonNegative);
+
+    // FIXME: Add support for <url>, <basic-shape>, <geometry-box>.
+    if (range.peek().functionId() != CSSValuePath)
+        return nullptr;
+
+    // FIXME: Add support for <fill-rule>.
+    CSSParserTokenRange functionRange = range;
+    CSSParserTokenRange functionArgs = consumeFunction(functionRange);
+
+    if (functionArgs.peek().type() != StringToken)
+        return nullptr;
+    String pathString = functionArgs.consumeIncludingWhitespace().value();
+    Path path;
+    if (!buildPathFromString(pathString, path) || !functionArgs.atEnd())
+        return nullptr;
+
+    range = functionRange;
+    return CSSPathValue::create(pathString);
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> consumeMotionRotation(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    RefPtrWillBeRawPtr<CSSValue> angle = consumeAngle(range, cssParserMode);
+    RefPtrWillBeRawPtr<CSSValue> keyword = consumeIdent<CSSValueAuto, CSSValueReverse>(range);
+    if (!angle && !keyword)
+        return nullptr;
+
+    if (!angle)
+        angle = consumeAngle(range, cssParserMode);
+
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    if (keyword)
+        list->append(keyword.release());
+    if (angle)
+        list->append(angle.release());
+    return list.release();
 }
 
 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty)
@@ -1638,12 +1670,15 @@
     case CSSPropertyWebkitTextDecorationsInEffect:
     case CSSPropertyTextDecorationLine:
         return consumeTextDecorationLine(m_range);
-    case CSSPropertyOutlineColor:
-        return consumeOutlineColor(m_range, m_context);
-    case CSSPropertyOutlineOffset:
-        return consumeLength(m_range, m_context.mode(), ValueRangeAll);
-    case CSSPropertyOutlineWidth:
-        return consumeLineWidth(m_range, m_context.mode());
+    case CSSPropertyMotionPath:
+        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
+        return consumeMotionPath(m_range);
+    case CSSPropertyMotionOffset:
+        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
+        return consumeLengthOrPercent(m_range, m_context.mode(), ValueRangeAll);
+    case CSSPropertyMotionRotation:
+        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
+        return consumeMotionRotation(m_range, m_context.mode());
     default:
         return nullptr;
     }
@@ -2109,14 +2144,17 @@
         // is disabled to match CSS 2.1 rules for parsing 'text-decoration'.
         if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
             return consumeShorthandGreedily(textDecorationShorthand(), important);
+        // TODO(rwlbuis): investigate if this shorthand hack can be removed.
+        m_currentShorthand = oldShorthand;
         RefPtrWillBeRawPtr<CSSValue> textDecoration = consumeTextDecorationLine(m_range);
         if (!textDecoration || !m_range.atEnd())
             return false;
         addProperty(CSSPropertyTextDecoration, textDecoration.release(), important);
         return true;
     }
-    case CSSPropertyOutline:
-        return consumeShorthandGreedily(outlineShorthand(), important);
+    case CSSPropertyMotion:
+        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
+        return consumeShorthandGreedily(motionShorthand(), important);
     default:
         m_currentShorthand = oldShorthand;
         return false;
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
index 5d4bd3e..31906a4 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -236,9 +236,6 @@
     PassRefPtrWillBeRawPtr<CSSValueList> parseTransform(bool useLegacyParsing);
     PassRefPtrWillBeRawPtr<CSSValue> parseTransformValue(bool useLegacyParsing, CSSParserValue*);
 
-    PassRefPtrWillBeRawPtr<CSSValue> parseMotionPath();
-    PassRefPtrWillBeRawPtr<CSSValue> parseMotionRotation();
-
     PassRefPtrWillBeRawPtr<CSSValue> parseTextEmphasisStyle();
 
     bool parseCalculation(CSSParserValue*, ValueRange);
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
index 7e524b6..64afe47 100644
--- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -39,7 +39,6 @@
 #include "core/css/CSSGridLineNamesValue.h"
 #include "core/css/CSSImageSetValue.h"
 #include "core/css/CSSImageValue.h"
-#include "core/css/CSSPathValue.h"
 #include "core/css/CSSPrimitiveValueMappings.h"
 #include "core/css/CSSProperty.h"
 #include "core/css/CSSPropertyMetadata.h"
@@ -57,7 +56,6 @@
 #include "core/css/parser/CSSParserValues.h"
 #include "core/frame/UseCounter.h"
 #include "core/style/GridCoordinate.h"
-#include "core/svg/SVGPathUtilities.h"
 #include "platform/RuntimeEnabledFeatures.h"
 
 namespace blink {
@@ -213,6 +211,7 @@
     case CSSPrimitiveValue::UnitType::Inches:
     case CSSPrimitiveValue::UnitType::Points:
     case CSSPrimitiveValue::UnitType::Picas:
+    case CSSPrimitiveValue::UnitType::UserUnits:
     case CSSPrimitiveValue::UnitType::ViewportWidth:
     case CSSPrimitiveValue::UnitType::ViewportHeight:
     case CSSPrimitiveValue::UnitType::ViewportMin:
@@ -420,6 +419,14 @@
         }
         break;
 
+    case CSSPropertyOutlineColor:        // <color> | invert | inherit
+        // Outline color has "invert" as additional keyword.
+        // Also, we want to allow the special focus color even in HTML Standard parsing mode.
+        if (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor) {
+            validPrimitive = true;
+            break;
+        }
+        /* nobreak */
     case CSSPropertyBackgroundColor: // <color> | inherit
     case CSSPropertyBorderTopColor: // <color> | inherit
     case CSSPropertyBorderRightColor:
@@ -601,6 +608,7 @@
             unitless = FUnitlessQuirk;
         // fall through
     case CSSPropertyWebkitTextStrokeWidth:
+    case CSSPropertyOutlineWidth: // <border-width> | inherit
     case CSSPropertyWebkitBorderStartWidth:
     case CSSPropertyWebkitBorderEndWidth:
     case CSSPropertyWebkitBorderBeforeWidth:
@@ -741,6 +749,9 @@
     case CSSPropertyBorderRadius:
     case CSSPropertyAliasWebkitBorderRadius:
         return parseBorderRadius(unresolvedProperty, important);
+    case CSSPropertyOutlineOffset:
+        validPrimitive = validUnit(value, FLength);
+        break;
     case CSSPropertyWebkitBoxReflect:
         if (id == CSSValueNone)
             validPrimitive = true;
@@ -888,26 +899,6 @@
         return true;
     }
 
-    case CSSPropertyMotion:
-        // <motion-path> && <motion-offset> && <motion-rotation>
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
-        return parseShorthand(propId, motionShorthand(), important);
-    case CSSPropertyMotionPath:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else
-            parsedValue = parseMotionPath();
-        break;
-    case CSSPropertyMotionOffset:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
-        validPrimitive = validUnit(value, FLength | FPercent);
-        break;
-    case CSSPropertyMotionRotation:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
-        parsedValue = parseMotionRotation();
-        break;
-
     case CSSPropertyJustifyContent:
         ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
         parsedValue = parseContentDistributionOverflowPosition();
@@ -1031,6 +1022,9 @@
         return parseShorthand(propId, webkitBorderBeforeShorthand(), important);
     case CSSPropertyWebkitBorderAfter:
         return parseShorthand(propId, webkitBorderAfterShorthand(), important);
+    case CSSPropertyOutline:
+        // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
+        return parseShorthand(propId, outlineShorthand(), important);
     case CSSPropertyBorderColor:
         // <color>{1,4} | inherit
         return parse4Values(propId, borderColorShorthand().properties(), important);
@@ -1195,10 +1189,10 @@
     case CSSPropertyWebkitTextDecorationsInEffect:
     case CSSPropertyTextDecorationLine:
     case CSSPropertyTextDecoration:
-    case CSSPropertyOutline:
-    case CSSPropertyOutlineColor:
-    case CSSPropertyOutlineWidth:
-    case CSSPropertyOutlineOffset:
+    case CSSPropertyMotionPath:
+    case CSSPropertyMotionOffset:
+    case CSSPropertyMotionRotation:
+    case CSSPropertyMotion:
         validPrimitive = false;
         break;
 
@@ -5957,54 +5951,4 @@
     return transformValue.release();
 }
 
-PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseMotionPath()
-{
-    CSSParserValue* value = m_valueList->current();
-
-    // FIXME: Add support for <url>, <basic-shape>, <geometry-box>.
-    if (value->m_unit != CSSParserValue::Function || value->function->id != CSSValuePath)
-        return nullptr;
-
-    // FIXME: Add support for <fill-rule>.
-    CSSParserValueList* functionArgs = value->function->args.get();
-    if (!functionArgs || functionArgs->size() != 1 || !functionArgs->current())
-        return nullptr;
-
-    CSSParserValue* arg = functionArgs->current();
-    if (arg->m_unit != CSSParserValue::String)
-        return nullptr;
-
-    String pathString = arg->string;
-    Path path;
-    if (!buildPathFromString(pathString, path))
-        return nullptr;
-
-    m_valueList->next();
-    return CSSPathValue::create(pathString);
-}
-
-PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseMotionRotation()
-{
-    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-    bool hasAutoOrReverse = false;
-    bool hasAngle = false;
-
-    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        if ((value->id == CSSValueAuto || value->id == CSSValueReverse) && !hasAutoOrReverse) {
-            list->append(cssValuePool().createIdentifierValue(value->id));
-            hasAutoOrReverse = true;
-        } else if (!hasAngle && validUnit(value, FAngle)) {
-            list->append(createPrimitiveNumericValue(value));
-            hasAngle = true;
-        } else {
-            break;
-        }
-    }
-
-    if (!list->length())
-        return nullptr;
-
-    return list.release();
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/resolver/MatchRequest.h b/third_party/WebKit/Source/core/css/resolver/MatchRequest.h
index 6eb1791..c56c474 100644
--- a/third_party/WebKit/Source/core/css/resolver/MatchRequest.h
+++ b/third_party/WebKit/Source/core/css/resolver/MatchRequest.h
@@ -33,9 +33,8 @@
 class MatchRequest {
     STACK_ALLOCATED();
 public:
-    MatchRequest(RuleSet* ruleSet, bool includeEmptyRules = false, const ContainerNode* scope = 0, const CSSStyleSheet* cssSheet = 0, unsigned styleSheetIndex = 0)
+    MatchRequest(RuleSet* ruleSet, const ContainerNode* scope = 0, const CSSStyleSheet* cssSheet = 0, unsigned styleSheetIndex = 0)
         : ruleSet(ruleSet)
-        , includeEmptyRules(includeEmptyRules)
         , scope(scope)
         , styleSheet(cssSheet)
         , styleSheetIndex(styleSheetIndex)
@@ -46,7 +45,6 @@
     }
 
     RawPtrWillBeMember<const RuleSet> ruleSet;
-    const bool includeEmptyRules;
     RawPtrWillBeMember<const ContainerNode> scope;
     RawPtrWillBeMember<const CSSStyleSheet> styleSheet;
     const unsigned styleSheetIndex;
diff --git a/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp
index e42cae5..d42cda2 100644
--- a/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp
@@ -148,7 +148,7 @@
 {
     for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) {
         ASSERT(m_authorStyleSheets[i]->ownerNode());
-        MatchRequest matchRequest(&m_authorStyleSheets[i]->contents()->ruleSet(), collector.includeEmptyRules(), &m_scope->rootNode(), m_authorStyleSheets[i], i);
+        MatchRequest matchRequest(&m_authorStyleSheets[i]->contents()->ruleSet(), &m_scope->rootNode(), m_authorStyleSheets[i], i);
         collector.collectMatchingRules(matchRequest, cascadeOrder);
     }
 }
@@ -157,7 +157,7 @@
 {
     for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) {
         ASSERT(m_authorStyleSheets[i]->ownerNode());
-        MatchRequest matchRequest(&m_authorStyleSheets[i]->contents()->ruleSet(), collector.includeEmptyRules(), &m_scope->rootNode(), m_authorStyleSheets[i], i);
+        MatchRequest matchRequest(&m_authorStyleSheets[i]->contents()->ruleSet(), &m_scope->rootNode(), m_authorStyleSheets[i], i);
         collector.collectMatchingShadowHostRules(matchRequest, cascadeOrder);
     }
 }
@@ -165,7 +165,7 @@
 void ScopedStyleResolver::collectMatchingTreeBoundaryCrossingRules(ElementRuleCollector& collector, CascadeOrder cascadeOrder)
 {
     for (const auto& rules : *m_treeBoundaryCrossingRuleSet) {
-        MatchRequest request(rules->m_ruleSet.get(), collector.includeEmptyRules(), &treeScope().rootNode(), rules->m_parentStyleSheet, rules->m_parentIndex);
+        MatchRequest request(rules->m_ruleSet.get(), &treeScope().rootNode(), rules->m_parentStyleSheet, rules->m_parentIndex);
         collector.collectMatchingRules(request, cascadeOrder, true);
     }
 }
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
index 804cd975..35ab44b 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -451,7 +451,6 @@
         }
     }
 
-    collector.setIncludeEmptyRules(false);
     matchAuthorRules(state.element(), collector);
 
     if (state.element()->isStyledElement()) {
@@ -790,7 +789,6 @@
         collector.setPseudoStyleRequest(pseudoStyleRequest);
 
         matchUARules(collector);
-        collector.setIncludeEmptyRules(false);
         matchAuthorRules(state.element(), collector);
         collector.finishAddingAuthorRulesForTreeScope();
 
@@ -1477,8 +1475,9 @@
 
     ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
     collector.setMode(SelectorChecker::CollectingStyleRules);
+    collector.setIncludeEmptyRules(true);
 
-    MatchRequest matchRequest(m_watchedSelectorsRules.get(), true);
+    MatchRequest matchRequest(m_watchedSelectorsRules.get());
     collector.collectMatchingRules(matchRequest);
     collector.sortAndTransferMatchedRules();
 
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 7d94d4e6a..e5f1af4 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -2907,6 +2907,7 @@
         return;
 
     m_url = newURL;
+    m_accessEntryFromURL = nullptr;
     updateBaseURL();
     contextFeatures().urlDidChange(this);
 }
@@ -3832,6 +3833,14 @@
     return s_eventFactory;
 }
 
+const OriginAccessEntry& Document::accessEntryFromURL()
+{
+    if (!m_accessEntryFromURL) {
+        m_accessEntryFromURL = adoptPtr(new OriginAccessEntry(url().protocol(), url().host(), OriginAccessEntry::AllowRegisterableDomains));
+    }
+    return *m_accessEntryFromURL;
+}
+
 void Document::registerEventFactory(PassOwnPtr<EventFactoryBase> eventFactory)
 {
     ASSERT(!eventFactories().contains(eventFactory.get()));
@@ -4040,7 +4049,7 @@
     // We're intentionally using the URL of each document rather than the document's SecurityOrigin.
     // Sandboxing a document into a unique origin shouldn't effect first-/third-party status for
     // cookies and site data.
-    OriginAccessEntry accessEntry(topDocument().url().protocol(), topDocument().url().host(), OriginAccessEntry::AllowRegisterableDomains);
+    const OriginAccessEntry& accessEntry = topDocument().accessEntryFromURL();
     const Document* currentDocument = this;
     while (currentDocument) {
         // Skip over srcdoc documents, as they are always same-origin with their closest non-srcdoc parent.
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 18669f2..a37c362e 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -137,6 +137,7 @@
 class NodeFilter;
 class NodeIterator;
 class NthIndexCache;
+class OriginAccessEntry;
 class Page;
 class PlatformMouseEvent;
 class ProcessingInstruction;
@@ -1150,6 +1151,8 @@
 
     void setNthIndexCache(NthIndexCache* nthIndexCache) { ASSERT(!m_nthIndexCache || !nthIndexCache); m_nthIndexCache = nthIndexCache; }
 
+    const OriginAccessEntry& accessEntryFromURL();
+
     // TODO(bokan): Temporarily moved this to the top of memebers so it's likely
     // to be included in a minidump memory region. crbug.com/519752
     LoadEventProgress m_loadEventProgress;
@@ -1184,6 +1187,7 @@
     KURL m_baseURLOverride; // An alternative base URL that takes precedence over m_baseURL (but not m_baseElementURL).
     KURL m_baseElementURL; // The URL set by the <base> element.
     KURL m_cookieURL; // The URL to use for cookie access.
+    OwnPtr<OriginAccessEntry> m_accessEntryFromURL;
 
     AtomicString m_baseTarget;
 
diff --git a/third_party/WebKit/Source/core/fetch/CachingCorrectnessTest.cpp b/third_party/WebKit/Source/core/fetch/CachingCorrectnessTest.cpp
index c772cf3..297b776e 100644
--- a/third_party/WebKit/Source/core/fetch/CachingCorrectnessTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/CachingCorrectnessTest.cpp
@@ -141,7 +141,7 @@
 
     private:
         // From blink::Platform:
-        virtual double currentTime()
+        double currentTimeSeconds() override
         {
             return kOriginalRequestDateAsDouble + m_elapsedSeconds;
         }
diff --git a/third_party/WebKit/Source/core/fetch/TextResource.cpp b/third_party/WebKit/Source/core/fetch/TextResource.cpp
index 5ec44e3..3286b800 100644
--- a/third_party/WebKit/Source/core/fetch/TextResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/TextResource.cpp
@@ -7,6 +7,7 @@
 
 #include "core/html/parser/TextResourceDecoder.h"
 #include "platform/SharedBuffer.h"
+#include "wtf/text/StringBuilder.h"
 
 namespace blink {
 
@@ -34,9 +35,15 @@
 {
     ASSERT(m_data);
 
-    String text = m_decoder->decode(m_data->data(), encodedSize());
-    text.append(m_decoder->flush());
-    return text;
+    StringBuilder builder;
+    const char* data;
+    unsigned position = 0;
+    while (unsigned length = m_data->getSomeData(data, position)) {
+        builder.append(m_decoder->decode(data, length));
+        position += length;
+    }
+    builder.append(m_decoder->flush());
+    return builder.toString();
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 8e5a9be6..597e7c8 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -2035,54 +2035,9 @@
 {
     ASSERT(m_frame->view() == this);
 
-    // Set our clip rect to be our contents.
-    IntRect clipRect = contentsToRootFrame(visibleContentRect(scrollbarInclusion));
-    if (!m_frame->deprecatedLocalOwner())
-        return clipRect;
-
-    // Take our owner element and get its clip rect.
-    // FIXME: Do we need to do this for remote frames?
-    HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
-    FrameView* parentView = ownerElement->document().view();
-    if (parentView)
-        clipRect.intersect(parentView->clipRectsForFrameOwner(ownerElement, nullptr));
-    return clipRect;
-}
-
-IntRect FrameView::clipRectsForFrameOwner(const HTMLFrameOwnerElement* ownerElement, IntRect* unobscuredRect) const
-{
-    ASSERT(ownerElement);
-
-    if (unobscuredRect)
-        *unobscuredRect = IntRect();
-
-    // The layoutObject can sometimes be null when style="display:none" interacts
-    // with external content and plugins.
-    if (!ownerElement->layoutObject())
-        return windowClipRect();
-
-    // If we have no layer, just return our window clip rect.
-    const PaintLayer* enclosingLayer = ownerElement->layoutObject()->enclosingLayer();
-    if (!enclosingLayer)
-        return windowClipRect();
-
-    // FIXME: childrenClipRect relies on compositingState, which is not necessarily up to date.
-    // https://code.google.com/p/chromium/issues/detail?id=343769
-    DisableCompositingQueryAsserts disabler;
-
-    // Apply the clip from the layer.
-    IntRect elementRect = contentsToRootFrame(pixelSnappedIntRect(enclosingLayer->clipper().childrenClipRect()));
-
-    if (unobscuredRect) {
-        *unobscuredRect = elementRect;
-
-        // If element is not in root frame, clip to the local frame.
-        // FIXME: Do we need to do this for remote frames?
-        if (m_frame->deprecatedLocalOwner())
-            unobscuredRect->intersect(contentsToRootFrame(visibleContentRect()));
-    }
-
-    return intersection(elementRect, windowClipRect());
+    LayoutRect clipRect(LayoutPoint(), LayoutSize(visibleContentSize(scrollbarInclusion)));
+    layoutView()->mapRectToPaintInvalidationBacking(layoutView()->containerForPaintInvalidation(), clipRect, nullptr);
+    return enclosingIntRect(clipRect);
 }
 
 bool FrameView::shouldUseIntegerScrollOffset() const
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index 4b049e70..e6884a7 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -167,9 +167,6 @@
 
     void adjustViewSize();
 
-    // |unobscuredRect| receives the clip rect that is not clipped to the root window. It may be nullptr.
-    IntRect clipRectsForFrameOwner(const HTMLFrameOwnerElement*, IntRect* unobscuredRect) const;
-
     // Scale used to convert incoming input events.
     float inputEventsScaleFactor() const;
 
@@ -367,6 +364,7 @@
     bool isScrollCornerVisible() const override;
     bool userInputScrollable(ScrollbarOrientation) const override;
     bool shouldPlaceVerticalScrollbarOnLeft() const override;
+
     LayoutRect scrollIntoView(
         const LayoutRect& rectInContent,
         const ScrollAlignment& alignX,
diff --git a/third_party/WebKit/Source/core/frame/Settings.in b/third_party/WebKit/Source/core/frame/Settings.in
index 6ec2da5..4ff73b5 100644
--- a/third_party/WebKit/Source/core/frame/Settings.in
+++ b/third_party/WebKit/Source/core/frame/Settings.in
@@ -93,6 +93,9 @@
 antialiasedClips2dCanvasEnabled initial=false
 accelerated2dCanvasMSAASampleCount type=int, initial=0
 
+# Indicate if scheduling png image encoder of canvas toBlob on idle periods is enabled
+idleCanvasImageEncodingEnabled initial=true
+
 # WebAudio support.
 webAudioEnabled initial=false
 
@@ -240,7 +243,7 @@
 
 # Experiment to have all APIs reflect the layout viewport.
 # crbug.com/489206 tracks the experiment.
-inertVisualViewport initial=false
+inertVisualViewport initial=true
 
 # The rubber-band overscroll effect is implemented in Blink and is being moved
 # to the compositor thread. This will be set to true and eventually removed.
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 9739590..593c65b 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -862,6 +862,12 @@
         DeviceOrientationAbsoluteSecureOrigin = 988,
         FontFaceConstructor = 989,
         ServiceWorkerControlledPage = 990,
+        MeterElementWithContinuousCapacityAppearance = 991,
+        MeterElementWithDiscreteCapacityAppearance = 992,
+        MeterElementWithMeterAppearance = 993,
+        MeterElementWithNoneAppearance = 994,
+        MeterElementWithRatingAppearance = 995,
+        MeterElementWithRelevancyAppearance = 996,
 
         // Add new features immediately above this line. Don't change assigned
         // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index bf12c2f..be8027d9 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -558,7 +558,7 @@
     RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data());
 
     RefPtr<CanvasAsyncBlobCreator> asyncCreatorRef = CanvasAsyncBlobCreator::create(imageDataRef.release(), encodingMimeType, imageData->size(), callback);
-    if (Platform::current()->isThreadedCompositingEnabled() && (encodingMimeType == DefaultMimeType)) {
+    if (document().settings()->idleCanvasImageEncodingEnabled() && Platform::current()->isThreadedCompositingEnabled() && (encodingMimeType == DefaultMimeType)) {
         asyncCreatorRef->scheduleAsyncBlobCreation(true);
     } else {
         asyncCreatorRef->scheduleAsyncBlobCreation(false, quality);
diff --git a/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp b/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
index 97587fa..d91601fe 100644
--- a/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
@@ -57,6 +57,28 @@
 
 LayoutObject* HTMLMeterElement::createLayoutObject(const ComputedStyle& style)
 {
+    switch (style.appearance()) {
+    case ContinuousCapacityLevelIndicatorPart:
+        UseCounter::count(document(), UseCounter::MeterElementWithContinuousCapacityAppearance);
+        break;
+    case DiscreteCapacityLevelIndicatorPart:
+        UseCounter::count(document(), UseCounter::MeterElementWithDiscreteCapacityAppearance);
+        break;
+    case MeterPart:
+        UseCounter::count(document(), UseCounter::MeterElementWithMeterAppearance);
+        break;
+    case NoControlPart:
+        UseCounter::count(document(), UseCounter::MeterElementWithNoneAppearance);
+        break;
+    case RatingLevelIndicatorPart:
+        UseCounter::count(document(), UseCounter::MeterElementWithRatingAppearance);
+        break;
+    case RelevancyLevelIndicatorPart:
+        UseCounter::count(document(), UseCounter::MeterElementWithRelevancyAppearance);
+        break;
+    default:
+        break;
+    }
     if (openShadowRoot() || !LayoutTheme::theme().supportsMeter(style.appearance()))
         return LayoutObject::createObject(this, style);
     return new LayoutMeter(this);
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
index 32b7725..e3dc53e2 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
@@ -26,7 +26,7 @@
 
 bool isDeadlineNearOrPassed(double deadlineSeconds)
 {
-    return (deadlineSeconds - SlackBeforeDeadline - Platform::current()->monotonicallyIncreasingTime() <= 0);
+    return (deadlineSeconds - SlackBeforeDeadline - Platform::current()->monotonicallyIncreasingTimeSeconds() <= 0);
 }
 
 } // anonymous namespace
diff --git a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
index 65d3f4c..989f2d8 100644
--- a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
+++ b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
@@ -92,7 +92,8 @@
 {
     unsigned index = contentRunIndexWithTallestColumns();
     LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : group().logicalTopInFlowThread();
-    return m_contentRuns[index].columnLogicalHeight(startOffset);
+    LayoutUnit logicalHeightEstimate = m_contentRuns[index].columnLogicalHeight(startOffset);
+    return std::max(logicalHeightEstimate, m_minimumColumnLogicalHeight);
 }
 
 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box)
@@ -107,16 +108,38 @@
 
     if (box.hasForcedBreakAfter())
         addContentRun(flowThreadOffset() + box.logicalHeight());
+
+    if (box.paginationBreakability() != LayoutBox::AllowAnyBreaks) {
+        LayoutUnit unsplittableLogicalHeight = box.logicalHeight();
+        if (box.isFloating())
+            unsplittableLogicalHeight += box.marginBefore() + box.marginAfter();
+        if (m_minimumColumnLogicalHeight < unsplittableLogicalHeight)
+            m_minimumColumnLogicalHeight = unsplittableLogicalHeight;
+    }
 }
 
 void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box)
 {
 }
 
+static inline LayoutUnit columnLogicalHeightRequirementForLine(const ComputedStyle& style, const RootInlineBox& lastLine)
+{
+    // We may require a certain minimum number of lines per page in order to satisfy
+    // orphans and widows, and that may affect the minimum page height.
+    unsigned minimumLineCount = std::max<unsigned>(style.hasAutoOrphans() ? 1 : style.orphans(), style.widows());
+    const RootInlineBox* firstLine = &lastLine;
+    for (unsigned i = 1; i < minimumLineCount && firstLine->prevRootBox(); i++)
+        firstLine = firstLine->prevRootBox();
+    return lastLine.lineBottomWithLeading() - firstLine->lineTopWithLeading();
+}
+
 void InitialColumnHeightFinder::examineLine(const RootInlineBox& line)
 {
     LayoutUnit lineTop = line.lineTopWithLeading();
     LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop;
+    LayoutUnit minimumLogialHeight = columnLogicalHeightRequirementForLine(line.block().styleRef(), line);
+    if (m_minimumColumnLogicalHeight < minimumLogialHeight)
+        m_minimumColumnLogicalHeight = minimumLogialHeight;
     ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut());
     if (isFirstAfterBreak(lineTopInFlowThread))
         recordStrutBeforeOffset(lineTopInFlowThread, line.paginationStrut());
diff --git a/third_party/WebKit/Source/core/layout/ColumnBalancer.h b/third_party/WebKit/Source/core/layout/ColumnBalancer.h
index daab0d9..161f5a0 100644
--- a/third_party/WebKit/Source/core/layout/ColumnBalancer.h
+++ b/third_party/WebKit/Source/core/layout/ColumnBalancer.h
@@ -138,6 +138,8 @@
     //
     // [1] http://www.w3.org/TR/css3-break/#parallel-flows
     Vector<LayoutUnit, 32> m_shortestStruts;
+
+    LayoutUnit m_minimumColumnLogicalHeight;
 };
 
 // If we have previously used InitialColumnHeightFinder to estimate an initial column height, and
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index 42eb1b93..f6994d9 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -375,26 +375,6 @@
     invalidateDisplayItemClientForStartOfContinuationsIfNeeded(*this);
 }
 
-static void addNextFloatingOrOutOfFlowSiblingsToBlock(LayoutBlock* block, LayoutBlock* container)
-{
-    LayoutObject* child = block->nextSibling();
-    while (child && child->isFloatingOrOutOfFlowPositioned()) {
-        LayoutObject* sibling = child->nextSibling();
-        container->moveChildTo(block, child, nullptr, false);
-        child = sibling;
-    }
-}
-
-static void addPreviousFloatingOrOutOfFlowSiblingsToBlock(LayoutBlock* block, LayoutBlock* container)
-{
-    LayoutObject* child = block->previousSibling();
-    while (child && child->isFloatingOrOutOfFlowPositioned()) {
-        LayoutObject* sibling = child->previousSibling();
-        container->moveChildTo(block, child, block->firstChild(), false);
-        child = sibling;
-    }
-}
-
 void LayoutBlock::addChildIgnoringContinuation(LayoutObject* newChild, LayoutObject* beforeChild)
 {
     if (beforeChild && beforeChild->parent() != this) {
@@ -469,9 +449,19 @@
             LayoutBlock* newBox = createAnonymousBlock();
             LayoutBox::addChild(newBox, beforeChild);
             // Reparent adjacent floating or out-of-flow siblings to the new box.
-            addPreviousFloatingOrOutOfFlowSiblingsToBlock(newBox, this);
+            LayoutObject* child = newBox->previousSibling();
+            while (child && child->isFloatingOrOutOfFlowPositioned()) {
+                LayoutObject* sibling = child->previousSibling();
+                moveChildTo(newBox, child, newBox->firstChild(), false);
+                child = sibling;
+            }
             newBox->addChild(newChild);
-            addNextFloatingOrOutOfFlowSiblingsToBlock(newBox, this);
+            child = newBox->nextSibling();
+            while (child && child->isFloatingOrOutOfFlowPositioned()) {
+                LayoutObject* sibling = child->nextSibling();
+                moveChildTo(newBox, child, nullptr, false);
+                child = sibling;
+            }
             return;
         }
     }
@@ -742,13 +732,6 @@
             && (!anonymousBlock->previousSibling() || (anonymousBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->previousSibling()->isFloating() && !anonymousBlock->previousSibling()->previousSibling()))
             && (!anonymousBlock->nextSibling() || (anonymousBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->nextSibling()->isFloating() && !anonymousBlock->nextSibling()->nextSibling()))) {
             collapseAnonymousBlockChild(this, anonymousBlock);
-        } else {
-            // If we have floating or out-of-flow siblings now adjacent to an anonymous block, fold them
-            // into it.
-            if (prev && prev->isAnonymousBlock())
-                addNextFloatingOrOutOfFlowSiblingsToBlock(toLayoutBlock(prev), this);
-            else if (next && next->isAnonymousBlock())
-                addPreviousFloatingOrOutOfFlowSiblingsToBlock(toLayoutBlock(next), this);
         }
     }
 
@@ -2671,12 +2654,6 @@
         flowThread->contentWasLaidOut(offsetFromLogicalTopOfFirstPage() + logicalTopOffsetAfterPagination);
 }
 
-void LayoutBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
-{
-    if (LayoutFlowThread* flowThread = flowThreadContainingBlock())
-        flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight);
-}
-
 LayoutUnit LayoutBlock::collapsedMarginBeforeForChild(const LayoutBox& child) const
 {
     // If the child has the same directionality as we do, then we can just return its
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.h b/third_party/WebKit/Source/core/layout/LayoutBlock.h
index bfdb61b34..de1c27804 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.h
@@ -454,11 +454,6 @@
     // applying any forced or unforced break, if needed.
     void paginatedContentWasLaidOut(LayoutUnit logicalTopOffsetAfterPagination);
 
-    // Update minimum page height required to avoid fragmentation where it shouldn't occur (inside
-    // unbreakable content, between orphans and widows, etc.). This will be used as a hint to the
-    // column balancer to help set a good minimum column height.
-    void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight);
-
     // Adjust from painting offsets to the local coords of this layoutObject
     void offsetForContents(LayoutPoint&) const;
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index e394118..862f15a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -737,17 +737,6 @@
     return newLogicalTop;
 }
 
-static inline LayoutUnit calculateMinimumPageHeight(const ComputedStyle& style, const RootInlineBox& lastLine)
-{
-    // We may require a certain minimum number of lines per page in order to satisfy
-    // orphans and widows, and that may affect the minimum page height.
-    unsigned lineCount = std::max<unsigned>(style.hasAutoOrphans() ? 1 : style.orphans(), style.widows());
-    const RootInlineBox* firstLine = &lastLine;
-    for (unsigned i = 1; i < lineCount && firstLine->prevRootBox(); i++)
-        firstLine = firstLine->prevRootBox();
-    return lastLine.lineBottomWithLeading() - firstLine->lineTopWithLeading();
-}
-
 static inline bool shouldSetStrutOnBlock(const LayoutBlockFlow& block, const RootInlineBox& lineBox, LayoutUnit lineLogicalOffset, int lineIndex, LayoutUnit remainingLogicalHeight)
 {
     bool wantsStrutOnBlock = false;
@@ -786,7 +775,6 @@
     // line and all following lines.
     LayoutUnit logicalOffset = lineBox.lineTopWithLeading();
     LayoutUnit lineHeight = lineBox.lineBottomWithLeading() - logicalOffset;
-    updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(styleRef(), lineBox));
     logicalOffset += delta;
     lineBox.setPaginationStrut(LayoutUnit());
     lineBox.setIsFirstAfterPageBreak(false);
@@ -836,7 +824,7 @@
     paginatedContentWasLaidOut(logicalOffset);
 }
 
-LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(LayoutBox& child, LayoutUnit logicalOffset)
+LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(LayoutBox& child, LayoutUnit logicalOffset) const
 {
     if (child.paginationBreakability() == AllowAnyBreaks)
         return logicalOffset;
@@ -845,7 +833,6 @@
     if (child.isFloating())
         childLogicalHeight += marginBeforeForChild(child) + marginAfterForChild(child);
     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
-    updateMinimumPageHeight(logicalOffset, childLogicalHeight);
     if (!pageLogicalHeight)
         return logicalOffset;
     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, AssociateWithLatterPage);
@@ -2887,6 +2874,14 @@
     // TODO(mstensho): But we *should*.
     if (isOutOfFlowPositioned())
         return false;
+    if (isLayoutFlowThread()) {
+        // Don't let the strut escape the fragmentation context and get lost.
+        // TODO(mstensho): If we're in a nested fragmentation context, we should ideally convert
+        // and propagate the strut to the outer fragmentation context, so that the inner one is
+        // fully pushed to the next outer fragmentainer, instead of taking up unusable space in the
+        // previous one. But currently we have no mechanism in place to handle this.
+        return false;
+    }
     LayoutBlock* containingBlock = this->containingBlock();
     return containingBlock && containingBlock->isLayoutBlockFlow();
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
index d9950520..cb05410 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -530,7 +530,7 @@
     // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
     void adjustLinePositionForPagination(RootInlineBox&, LayoutUnit& deltaOffset);
     // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
-    LayoutUnit adjustForUnsplittableChild(LayoutBox&, LayoutUnit logicalOffset);
+    LayoutUnit adjustForUnsplittableChild(LayoutBox&, LayoutUnit logicalOffset) const;
 
     // Used to store state between styleWillChange and styleDidChange
     static bool s_canPropagateFloatIntoSibling;
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutFlowThread.h
index 32270f25..7883a0b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlowThread.h
+++ b/third_party/WebKit/Source/core/layout/LayoutFlowThread.h
@@ -88,7 +88,6 @@
     LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule);
 
     virtual void contentWasLaidOut(LayoutUnit logicalTopInFlowThreadAfterPagination) = 0;
-    virtual void updateMinimumPageHeight(LayoutUnit /*offset*/, LayoutUnit /*minHeight*/) { }
 
     virtual bool isPageLogicalHeightKnown() const { return true; }
     bool pageLogicalSizeChanged() const { return m_pageLogicalSizeChanged; }
diff --git a/third_party/WebKit/Source/core/layout/LayoutImage.cpp b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
index 81810151..8e8ecfc 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImage.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
@@ -185,7 +185,7 @@
         updateInnerContentRect();
     }
 
-    if (imageResource() && imageResource()->image() && imageResource()->image()->maybeAnimated())
+    if (imageResource() && imageResource()->maybeAnimated())
         setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull);
     else
         setShouldDoFullPaintInvalidation(PaintInvalidationFull);
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp b/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
index 85e24d6..4c4ceb9 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
@@ -83,7 +83,7 @@
     if (!m_cachedImage)
         return;
 
-    image()->resetAnimation();
+    m_cachedImage->image()->resetAnimation();
 
     m_layoutObject->setShouldDoFullPaintInvalidation();
 }
@@ -105,4 +105,10 @@
     return size;
 }
 
+bool LayoutImageResource::maybeAnimated() const
+{
+    Image* image = m_cachedImage ? m_cachedImage->image() : Image::nullImage();
+    return image->maybeAnimated();
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResource.h b/third_party/WebKit/Source/core/layout/LayoutImageResource.h
index a4d99baf..788e794 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResource.h
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResource.h
@@ -53,8 +53,9 @@
     virtual bool hasImage() const { return m_cachedImage; }
 
     void resetAnimation();
+    bool maybeAnimated() const;
 
-    virtual PassRefPtr<Image> image(int /* width */ = 0, int /* height */ = 0) const
+    virtual PassRefPtr<Image> image(const IntSize&) const
     {
         return m_cachedImage ? m_cachedImage->imageForLayoutObject(m_layoutObject) : Image::nullImage();
     }
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.cpp b/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.cpp
index aff05ffb..12c68f3 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.cpp
@@ -61,12 +61,12 @@
     m_cachedImage = 0;
 }
 
-PassRefPtr<Image> LayoutImageResourceStyleImage::image(int width, int height) const
+PassRefPtr<Image> LayoutImageResourceStyleImage::image(const IntSize& size) const
 {
     // Generated content may trigger calls to image() while we're still pending, don't assert but gracefully exit.
     if (m_styleImage->isPendingImage())
         return nullptr;
-    return m_styleImage->image(m_layoutObject, IntSize(width, height));
+    return m_styleImage->image(m_layoutObject, size);
 }
 
 void LayoutImageResourceStyleImage::setContainerSizeForLayoutObject(const IntSize& size)
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.h b/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.h
index 0dd704d8..3ed1625d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.h
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.h
@@ -46,7 +46,7 @@
     void shutdown() override;
 
     bool hasImage() const override { return true; }
-    PassRefPtr<Image> image(int width = 0, int height = 0) const override;
+    PassRefPtr<Image> image(const IntSize&) const override;
     bool errorOccurred() const override { return m_styleImage->errorOccurred(); }
 
     void setContainerSizeForLayoutObject(const IntSize&) override;
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
index 4298a5a..5e2ad6f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
@@ -928,10 +928,4 @@
     appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination);
 }
 
-void LayoutMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
-{
-    if (LayoutMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset))
-        multicolSet->updateMinimumColumnHeight(offset, minHeight);
-}
-
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
index 2a9278f..057fec7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
@@ -227,7 +227,6 @@
     void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override;
     void updateLogicalWidth() override;
     void contentWasLaidOut(LayoutUnit logicalTopInFlowThreadAfterPagination) override;
-    void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight) override;
 
     // The last set we worked on. It's not to be used as the "current set". The concept of a
     // "current set" is difficult, since layout may jump back and forth in the tree, due to wrong
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
index 11bddd08..378540b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
@@ -209,11 +209,6 @@
     return row.visualPointToFlowThreadPoint(visualPoint - row.offsetFromColumnSet());
 }
 
-void LayoutMultiColumnSet::updateMinimumColumnHeight(LayoutUnit offsetInFlowThread, LayoutUnit height)
-{
-    fragmentainerGroupAtFlowThreadOffset(offsetInFlowThread).updateMinimumColumnHeight(height);
-}
-
 LayoutUnit LayoutMultiColumnSet::pageLogicalTopForOffset(LayoutUnit offset) const
 {
     return fragmentainerGroupAtFlowThreadOffset(offset).columnLogicalTopForOffset(offset);
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h
index 2f29d06a0..c5884e9 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.h
@@ -111,8 +111,6 @@
 
     LayoutPoint visualPointToFlowThreadPoint(const LayoutPoint& visualPoint) const;
 
-    void updateMinimumColumnHeight(LayoutUnit offsetInFlowThread, LayoutUnit height);
-
     // (Re-)calculate the column height if it's auto. This is first and foremost needed by sets that
     // are to balance the column height, but even when it isn't to be balanced, this is necessary if
     // the multicol container's height is constrained.
diff --git a/third_party/WebKit/Source/core/layout/LayoutPart.cpp b/third_party/WebKit/Source/core/layout/LayoutPart.cpp
index c22e254d..4741abc 100644
--- a/third_party/WebKit/Source/core/layout/LayoutPart.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutPart.cpp
@@ -315,7 +315,7 @@
         contentBox.setLocation(absoluteContentBox.location());
         return setWidgetGeometry(contentBox);
     }
-
+    // TODO(chrishtr): why are these widgets using an absolute rect for their frameRect?
     return setWidgetGeometry(absoluteContentBox);
 }
 
diff --git a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
index 0acf7d3..e9246bf 100644
--- a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
+++ b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
@@ -49,9 +49,6 @@
 
 void MultiColumnFragmentainerGroup::resetColumnHeight()
 {
-    // Nuke previously stored minimum column height. Contents may have changed for all we know.
-    m_minimumColumnHeight = 0;
-
     m_maxColumnHeight = calculateMaxColumnHeight();
 
     LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
@@ -346,7 +343,7 @@
         // content run (after having "inserted" implicit breaks), and find its start offset (by
         // looking at the previous run's end offset, or, if there's no previous run, the set's start
         // offset in the flow thread).
-        return std::max(InitialColumnHeightFinder::initialMinimalBalancedHeight(*this), m_minimumColumnHeight);
+        return InitialColumnHeightFinder::initialMinimalBalancedHeight(*this);
     }
 
     if (actualColumnCount() <= m_columnSet.usedColumnCount()) {
diff --git a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
index a78072e..54116a34 100644
--- a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
+++ b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.h
@@ -61,7 +61,6 @@
 
     bool heightIsAuto() const;
     void resetColumnHeight();
-    void updateMinimumColumnHeight(LayoutUnit height) { m_minimumColumnHeight = std::max(height, m_minimumColumnHeight); }
     bool recalculateColumnHeight(BalancedColumnHeightCalculation calculationMode);
 
     LayoutSize flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread) const;
@@ -113,9 +112,7 @@
 
     LayoutUnit m_columnHeight;
 
-    // The following variables are used when balancing the column set.
     LayoutUnit m_maxColumnHeight; // Maximum column height allowed.
-    LayoutUnit m_minimumColumnHeight;
 };
 
 // List of all fragmentainer groups within a column set. There will always be at least one
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
index aa46e439..60bd3291 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -804,7 +804,7 @@
 {
     IntRect defaultClip;
     if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled() && !clip) {
-        defaultClip.setSize(m_layoutView.layoutSize(IncludeScrollbars));
+        defaultClip.setSize(expandedIntSize(graphicsLayer->size()));
         clip = &defaultClip;
     }
     ASSERT(clip);
diff --git a/third_party/WebKit/Source/core/paint/ImagePainter.cpp b/third_party/WebKit/Source/core/paint/ImagePainter.cpp
index 8a94b3c..fc4d51c 100644
--- a/third_party/WebKit/Source/core/paint/ImagePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ImagePainter.cpp
@@ -128,7 +128,7 @@
     if (alignedRect.width() <= 0 || alignedRect.height() <= 0)
         return;
 
-    RefPtr<Image> image = m_layoutImage.imageResource()->image(alignedRect.width(), alignedRect.height());
+    RefPtr<Image> image = m_layoutImage.imageResource()->image(alignedRect.size());
     if (!image || image->isNull())
         return;
 
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
index 143a3c7..77b507f 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
@@ -29,10 +29,10 @@
 
     if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) {
         EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 4,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(textInlineBox, foregroundType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
         GraphicsContext context(rootPaintController());
         PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 800, 600), GlobalPaintNormalPhase, LayoutSize());
@@ -49,11 +49,11 @@
 
     if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) {
         EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 5,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(textInlineBox, foregroundType),
             TestDisplayItem(divLayoutObject, DisplayItem::Caret), // New!
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
         GraphicsContext context(rootPaintController());
         PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 800, 600), GlobalPaintNormalPhase, LayoutSize());
@@ -78,10 +78,10 @@
 
     if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) {
         EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 4,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(firstTextBox, foregroundType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
         GraphicsContext context(rootPaintController());
         PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 800, 600), GlobalPaintNormalPhase, LayoutSize());
@@ -102,11 +102,11 @@
 
     if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) {
         EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 5,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(newFirstTextBox, foregroundType),
             TestDisplayItem(secondTextBox, foregroundType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
         GraphicsContext context(rootPaintController());
         PaintLayerPaintingInfo paintingInfo(&rootLayer, LayoutRect(0, 0, 800, 600), GlobalPaintNormalPhase, LayoutSize());
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
index 6e415581..117de103 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
@@ -141,9 +141,6 @@
 const DisplayItem::Type cachedBackgroundType = DisplayItem::drawingTypeToCachedDrawingType(backgroundType);
 const DisplayItem::Type foregroundType = DisplayItem::paintPhaseToDrawingType(PaintPhaseForeground);
 const DisplayItem::Type cachedForegroundType = DisplayItem::drawingTypeToCachedDrawingType(foregroundType);
-const DisplayItem::Type subsequenceType = DisplayItem::SubsequenceNormalFlowAndPositiveZOrder;
-const DisplayItem::Type endSubsequenceType = DisplayItem::subsequenceTypeToEndSubsequenceType(subsequenceType);
-const DisplayItem::Type cachedSubsequenceType = DisplayItem::subsequenceTypeToCachedSubsequenceType(subsequenceType);
 
 } // namespace blink
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
index 989dc1c8..7bb1bae 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -170,18 +170,6 @@
     }
 }
 
-LayoutRect PaintLayerClipper::childrenClipRect() const
-{
-    // FIXME: border-radius not accounted for.
-    // FIXME: Flow thread based columns not accounted for.
-    PaintLayer* clippingRootLayer = clippingRootForPainting();
-    LayoutRect layerBounds;
-    ClipRect backgroundRect, foregroundRect;
-    // Need to use uncached clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>).
-    ClipRectsContext context(clippingRootLayer, UncachedClipRects);
-    calculateRects(context, LayoutRect(m_layoutObject.view()->unscaledDocumentRect()), layerBounds, backgroundRect, foregroundRect);
-    return LayoutRect(clippingRootLayer->layoutObject()->localToAbsoluteQuad(FloatQuad(FloatRect(foregroundRect.rect()))).enclosingBoundingBox());
-}
 
 LayoutRect PaintLayerClipper::localClipRect(const PaintLayer* clippingRootLayer) const
 {
@@ -326,30 +314,6 @@
         calculateClipRects(context, clipRects);
 }
 
-PaintLayer* PaintLayerClipper::clippingRootForPainting() const
-{
-    const PaintLayer* current = m_layoutObject.layer();
-    // FIXME: getting rid of current->hasCompositedLayerMapping() here breaks the
-    // compositing/backing/no-backing-for-clip.html layout test, because there is a
-    // "composited but paints into ancestor" layer involved. However, it doesn't make sense that
-    // that check would be appropriate here but not inside the while loop below.
-    if (current->isPaintInvalidationContainer() || current->hasCompositedLayerMapping())
-        return const_cast<PaintLayer*>(current);
-
-    while (current) {
-        if (current->isRootLayer())
-            return const_cast<PaintLayer*>(current);
-
-        current = current->compositingContainer();
-        ASSERT(current);
-        if (current->transform() || current->isPaintInvalidationContainer())
-            return const_cast<PaintLayer*>(current);
-    }
-
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
 bool PaintLayerClipper::shouldRespectOverflowClip(const ClipRectsContext& context) const
 {
     PaintLayer* layer = m_layoutObject.layer();
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.h b/third_party/WebKit/Source/core/paint/PaintLayerClipper.h
index 2092d7f9..0c04bea8 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.h
@@ -147,7 +147,7 @@
 // #container and #fixed are siblings in the paint tree but #container does
 // clip #fixed. This is the reason why we compute the painting clip rects during
 // a layout tree walk and cache them for painting.
-class PaintLayerClipper {
+class CORE_EXPORT PaintLayerClipper {
     DISALLOW_NEW();
     WTF_MAKE_NONCOPYABLE(PaintLayerClipper);
 public:
@@ -156,8 +156,6 @@
     void clearClipRectsIncludingDescendants();
     void clearClipRectsIncludingDescendants(ClipRectsCacheSlot);
 
-    LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
-
     // Returns the background clip rect of the layer in the local coordinate space. Only looks for clips up to the given ancestor.
     LayoutRect localClipRect(const PaintLayer* ancestorLayer) const;
 
@@ -184,8 +182,6 @@
     }
     void getOrCalculateClipRects(const ClipRectsContext&, ClipRects&) const;
 
-    PaintLayer* clippingRootForPainting() const;
-
     ClipRectsCache& cache() const
     {
         if (!m_cache)
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index 5477d3a8..4e6850d 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -213,11 +213,34 @@
     if (m_paintLayer.layoutObject()->isLayoutPart() && toLayoutPart(m_paintLayer.layoutObject())->isThrottledFrameView())
         return FullyPainted;
 
-    PaintLayerPaintingInfo paintingInfo = paintingInfoArg;
-
     // Ensure our lists are up-to-date.
     m_paintLayer.stackingNode()->updateLayerListsIfNeeded();
 
+    Optional<SubsequenceRecorder> subsequenceRecorder;
+    if (!paintingInfoArg.disableSubsequenceCache
+        && !context->printing()
+        && !(paintingInfoArg.globalPaintFlags() & GlobalPaintFlattenCompositingLayers)
+        && !(paintFlags & (PaintLayerPaintingReflection | PaintLayerPaintingRootBackgroundOnly | PaintLayerPaintingOverlayScrollbars))
+        && m_paintLayer.stackingNode()->isStackingContext()
+        && PaintLayerStackingNodeIterator(*m_paintLayer.stackingNode(), AllChildren).next()) {
+        if (!m_paintLayer.needsRepaint()
+            && paintingInfoArg.scrollOffsetAccumulation == m_paintLayer.previousScrollOffsetAccumulationForPainting()
+            && SubsequenceRecorder::useCachedSubsequenceIfPossible(*context, m_paintLayer))
+            return result;
+        subsequenceRecorder.emplace(*context, m_paintLayer);
+    }
+
+    PaintLayerPaintingInfo paintingInfo = paintingInfoArg;
+
+    // This is a workaround of ancestor clip change issue (crbug.com/533717).
+    // TODO(wangxianzhu):
+    // - spv1: This disables subsequence cache for all descendants of LayoutView with root-layer-scrolls because
+    //   LayoutView has overflow clip. Should find another workaround method working with root-layer-scrolls
+    //   if it ships before slimming paint v2. crbug.com/552030.
+    // - spv2: Ensure subsequence cache works with ancestor clip change. crbug.com/536138.
+    if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_paintLayer.layoutObject()->hasClipOrOverflowClip())
+        paintingInfo.disableSubsequenceCache = true;
+
     LayoutPoint offsetFromRoot;
     m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
 
@@ -331,6 +354,11 @@
 
     m_paintLayer.setPreviousScrollOffsetAccumulationForPainting(paintingInfoArg.scrollOffsetAccumulation);
 
+    // Set subsequence not cacheable if the bounding box of this layer and descendants is not fully contained
+    // by paintRect, because later paintRect changes may expose new contents which will need repainting.
+    if (result == MaybeNotFullyPainted && subsequenceRecorder)
+        subsequenceRecorder->setUncacheable();
+
     return result;
 }
 
@@ -467,34 +495,10 @@
     if (!child)
         return result;
 
-    DisplayItem::Type subsequenceType;
-    if (childrenToVisit == NegativeZOrderChildren) {
-        subsequenceType = DisplayItem::SubsequenceNegativeZOrder;
-    } else {
-        ASSERT(childrenToVisit == (NormalFlowChildren | PositiveZOrderChildren));
-        subsequenceType = DisplayItem::SubsequenceNormalFlowAndPositiveZOrder;
-    }
-
-    Optional<SubsequenceRecorder> subsequenceRecorder;
-    if (!paintingInfo.disableSubsequenceCache
-        && !context->printing()
-        && m_paintLayer.stackingNode()->isStackingContext()
-        && !(paintingInfo.globalPaintFlags() & GlobalPaintFlattenCompositingLayers)
-        && !(paintFlags & (PaintLayerPaintingReflection | PaintLayerPaintingRootBackgroundOnly | PaintLayerPaintingOverlayScrollbars))) {
-        if (!m_paintLayer.needsRepaint()
-            && paintingInfo.scrollOffsetAccumulation == m_paintLayer.previousScrollOffsetAccumulationForPainting()
-            && SubsequenceRecorder::useCachedSubsequenceIfPossible(*context, m_paintLayer, subsequenceType))
-            return result;
-        subsequenceRecorder.emplace(*context, m_paintLayer, subsequenceType);
-    }
-
     IntSize scrollOffsetAccumulationForChildren = paintingInfo.scrollOffsetAccumulation;
     if (m_paintLayer.layoutObject()->hasOverflowClip())
         scrollOffsetAccumulationForChildren += m_paintLayer.layoutBox()->scrolledContentOffset();
 
-    bool disableChildSubsequenceCache = !RuntimeEnabledFeatures::slimmingPaintV2Enabled()
-        && (m_paintLayer.layoutObject()->hasOverflowClip() || m_paintLayer.layoutObject()->hasClip());
-
     for (; child; child = iterator.next()) {
         PaintLayerPainter childPainter(*child->layer());
         // If this Layer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents()
@@ -503,7 +507,6 @@
             continue;
 
         PaintLayerPaintingInfo childPaintingInfo = paintingInfo;
-        childPaintingInfo.disableSubsequenceCache = disableChildSubsequenceCache;
         childPaintingInfo.scrollOffsetAccumulation = scrollOffsetAccumulationForChildren;
         // Rare case: accumulate scroll offset of non-stacking-context ancestors up to m_paintLayer.
         for (PaintLayer* parentLayer = child->layer()->parent(); parentLayer != &m_paintLayer; parentLayer = parentLayer->parent()) {
@@ -515,11 +518,6 @@
             result = MaybeNotFullyPainted;
     }
 
-    // Set subsequence not cacheable if the bounding box of this layer and descendants is not fully contained
-    // by paintRect, because later paintRect changes may expose new contents which will need repainting.
-    if (result == MaybeNotFullyPainted && subsequenceRecorder)
-        subsequenceRecorder->setUncacheable();
-
     return result;
 }
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
index 65b2c8d8..5b8c64a 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
@@ -46,33 +46,29 @@
     LayoutObject& content2 = *document().getElementById("content2")->layoutObject();
 
     if (rootLayerScrolls) {
-        EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11,
+        EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 7,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(container1, backgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
             TestDisplayItem(container2, backgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
         EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 13,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
-            TestDisplayItem(htmlLayer, subsequenceType),
+            TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
+            TestDisplayItem(container1Layer, DisplayItem::Subsequence),
             TestDisplayItem(container1, backgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
+            TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(container2Layer, DisplayItem::Subsequence),
             TestDisplayItem(container2, backgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
-            TestDisplayItem(htmlLayer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     }
 
     toHTMLElement(content1.node())->setAttribute(HTMLNames::styleAttr, "position: absolute; width: 100px; height: 100px; background-color: green");
@@ -80,61 +76,54 @@
     paint();
 
     if (rootLayerScrolls) {
-        EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 9,
+        EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 7,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), cachedBackgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(container1, cachedBackgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
             TestDisplayItem(container2, cachedBackgroundType),
-            TestDisplayItem(container2Layer, cachedSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(content2, cachedBackgroundType),
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
-        EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 11,
+        EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 10,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), cachedBackgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
-            TestDisplayItem(htmlLayer, subsequenceType),
+            TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
+            TestDisplayItem(container1Layer, DisplayItem::Subsequence),
             TestDisplayItem(container1, cachedBackgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
-            TestDisplayItem(container2, cachedBackgroundType),
-            TestDisplayItem(container2Layer, cachedSubsequenceType),
-            TestDisplayItem(htmlLayer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(container2Layer, DisplayItem::CachedSubsequence),
+            TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     }
 
     commit();
 
     if (rootLayerScrolls) {
-        EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11,
+        EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 7,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(container1, backgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
             TestDisplayItem(container2, backgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
         EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 13,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
-            TestDisplayItem(htmlLayer, subsequenceType),
+            TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
+            TestDisplayItem(container1Layer, DisplayItem::Subsequence),
             TestDisplayItem(container1, backgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
+            TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(container2Layer, DisplayItem::Subsequence),
             TestDisplayItem(container2, backgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
-            TestDisplayItem(htmlLayer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     }
 }
 
@@ -179,41 +168,35 @@
     // Content2b is out of the interest rect and output nothing;
     // Container3 is partly in the interest rect.
     if (rootLayerScrolls) {
-        EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 15,
+        EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 9,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(container1, backgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
             TestDisplayItem(container2, backgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2a, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
             TestDisplayItem(container3, backgroundType),
-            TestDisplayItem(container3Layer, subsequenceType),
             TestDisplayItem(content3, backgroundType),
-            TestDisplayItem(container3Layer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
         EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 17,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
-            TestDisplayItem(htmlLayer, subsequenceType),
+            TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
+            TestDisplayItem(container1Layer, DisplayItem::Subsequence),
             TestDisplayItem(container1, backgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
+            TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(container2Layer, DisplayItem::Subsequence),
             TestDisplayItem(container2, backgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2a, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
+            TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(container3Layer, DisplayItem::Subsequence),
             TestDisplayItem(container3, backgroundType),
-            TestDisplayItem(container3Layer, subsequenceType),
             TestDisplayItem(content3, backgroundType),
-            TestDisplayItem(container3Layer, endSubsequenceType),
-            TestDisplayItem(htmlLayer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(container3Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     }
 
     updateLifecyclePhasesBeforePaint();
@@ -227,65 +210,58 @@
     // Container3 becomes out of the interest rect and outputs nothing.
 
     if (rootLayerScrolls) {
-        EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 10,
+        EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 8,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), cachedBackgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(container1, cachedBackgroundType),
-            TestDisplayItem(container1Layer, cachedSubsequenceType),
+            TestDisplayItem(content1, cachedBackgroundType),
             TestDisplayItem(container2, cachedBackgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2a, cachedBackgroundType),
             TestDisplayItem(content2b, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
-        EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 12,
+        EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 11,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), cachedBackgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
-            TestDisplayItem(htmlLayer, subsequenceType),
-            TestDisplayItem(container1, cachedBackgroundType),
-            TestDisplayItem(container1Layer, cachedSubsequenceType),
+            TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
+            TestDisplayItem(container1Layer, DisplayItem::CachedSubsequence),
+            TestDisplayItem(container2Layer, DisplayItem::Subsequence),
             TestDisplayItem(container2, cachedBackgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2a, cachedBackgroundType),
             TestDisplayItem(content2b, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
-            TestDisplayItem(htmlLayer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     }
 
     commit();
 
     if (rootLayerScrolls) {
-        EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 12,
+        EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 8,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
             TestDisplayItem(container1, backgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
             TestDisplayItem(container2, backgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2a, backgroundType),
             TestDisplayItem(content2b, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     } else {
         EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 14,
+            TestDisplayItem(rootLayer, DisplayItem::Subsequence),
             TestDisplayItem(layoutView(), backgroundType),
-            TestDisplayItem(rootLayer, subsequenceType),
-            TestDisplayItem(htmlLayer, subsequenceType),
+            TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
+            TestDisplayItem(container1Layer, DisplayItem::Subsequence),
             TestDisplayItem(container1, backgroundType),
-            TestDisplayItem(container1Layer, subsequenceType),
             TestDisplayItem(content1, backgroundType),
-            TestDisplayItem(container1Layer, endSubsequenceType),
+            TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(container2Layer, DisplayItem::Subsequence),
             TestDisplayItem(container2, backgroundType),
-            TestDisplayItem(container2Layer, subsequenceType),
             TestDisplayItem(content2a, backgroundType),
             TestDisplayItem(content2b, backgroundType),
-            TestDisplayItem(container2Layer, endSubsequenceType),
-            TestDisplayItem(htmlLayer, endSubsequenceType),
-            TestDisplayItem(rootLayer, endSubsequenceType));
+            TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
+            TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
+            TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
     }
 }
 
diff --git a/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp b/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
index f6da1bc..1f1be38 100644
--- a/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
@@ -51,7 +51,7 @@
 
 void SVGImagePainter::paintForeground(const PaintInfo& paintInfo)
 {
-    RefPtr<Image> image = m_layoutSVGImage.imageResource()->image();
+    RefPtr<Image> image = m_layoutSVGImage.imageResource()->image(IntSize());
     FloatRect destRect = m_layoutSVGImage.objectBoundingBox();
     FloatRect srcRect(0, 0, image->width(), image->height());
 
diff --git a/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp b/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
index 724cbf1..28b5a90 100644
--- a/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
@@ -38,10 +38,10 @@
     commit();
 
     EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 4,
+        TestDisplayItem(rootLayer, DisplayItem::Subsequence),
         TestDisplayItem(layoutView, DisplayItem::BoxDecorationBackground),
-        TestDisplayItem(rootLayer, subsequenceType),
         TestDisplayItem(cell1, DisplayItem::TableCellBackgroundFromRow),
-        TestDisplayItem(rootLayer, endSubsequenceType));
+        TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
 
     updateLifecyclePhasesBeforePaint();
     interestRect = IntRect(0, 300, 200, 1000);
@@ -49,10 +49,10 @@
     commit();
 
     EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 4,
+        TestDisplayItem(rootLayer, DisplayItem::Subsequence),
         TestDisplayItem(layoutView, DisplayItem::BoxDecorationBackground),
-        TestDisplayItem(rootLayer, subsequenceType),
         TestDisplayItem(cell2, DisplayItem::TableCellBackgroundFromRow),
-        TestDisplayItem(rootLayer, endSubsequenceType));
+        TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp b/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp
index ade7ec1..a22e1f5 100644
--- a/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp
@@ -49,7 +49,7 @@
 
     if (es.hadException()) {
         parseError = ParsingAttributeFailedError;
-        baseValue()->newValueSpecifiedUnits(LengthTypeNumber, 0);
+        baseValue()->newValueSpecifiedUnits(CSSPrimitiveValue::UnitType::UserUnits, 0);
     } else if (m_negativeValuesMode == ForbidNegativeLengths && baseValue()->valueInSpecifiedUnits() < 0) {
         parseError = NegativeValueForbiddenError;
     }
diff --git a/third_party/WebKit/Source/core/svg/SVGLength.cpp b/third_party/WebKit/Source/core/svg/SVGLength.cpp
index decc141..075649f 100644
--- a/third_party/WebKit/Source/core/svg/SVGLength.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGLength.cpp
@@ -26,6 +26,9 @@
 #include "bindings/core/v8/ExceptionState.h"
 #include "core/SVGNames.h"
 #include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSValue.h"
+#include "core/css/CSSValuePool.h"
+#include "core/css/parser/CSSParser.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/svg/SVGAnimationElement.h"
 #include "core/svg/SVGParserUtilities.h"
@@ -35,115 +38,27 @@
 
 namespace blink {
 
-namespace {
-
-inline const char* lengthTypeToString(SVGLengthType type)
-{
-    switch (type) {
-    case LengthTypeUnknown:
-    case LengthTypeNumber:
-        return "";
-    case LengthTypePercentage:
-        return "%";
-    case LengthTypeEMS:
-        return "em";
-    case LengthTypeEXS:
-        return "ex";
-    case LengthTypePX:
-        return "px";
-    case LengthTypeCM:
-        return "cm";
-    case LengthTypeMM:
-        return "mm";
-    case LengthTypeIN:
-        return "in";
-    case LengthTypePT:
-        return "pt";
-    case LengthTypePC:
-        return "pc";
-    case LengthTypeREMS:
-        return "rem";
-    case LengthTypeCHS:
-        return "ch";
-    }
-
-    ASSERT_NOT_REACHED();
-    return "";
-}
-
-template<typename CharType>
-SVGLengthType stringToLengthType(const CharType*& ptr, const CharType* end)
-{
-    if (ptr == end)
-        return LengthTypeNumber;
-
-    SVGLengthType type = LengthTypeUnknown;
-    const CharType firstChar = *ptr++;
-
-    if (firstChar == '%') {
-        type = LengthTypePercentage;
-    } else if (isHTMLSpace<CharType>(firstChar)) {
-        type = LengthTypeNumber;
-    } else if (ptr < end) {
-        const CharType secondChar = *ptr++;
-
-        if (firstChar == 'p') {
-            if (secondChar == 'x')
-                type = LengthTypePX;
-            if (secondChar == 't')
-                type = LengthTypePT;
-            if (secondChar == 'c')
-                type = LengthTypePC;
-        } else if (firstChar == 'e') {
-            if (secondChar == 'm')
-                type = LengthTypeEMS;
-            if (secondChar == 'x')
-                type = LengthTypeEXS;
-        } else if (firstChar == 'r') {
-            if (secondChar == 'e' && ptr < end) {
-                const CharType thirdChar = *ptr++;
-                if (thirdChar == 'm')
-                    type = LengthTypeREMS;
-            }
-        } else if (firstChar == 'c') {
-            if (secondChar == 'h')
-                type = LengthTypeCHS;
-            if (secondChar == 'm')
-                type = LengthTypeCM;
-        } else if (firstChar == 'm' && secondChar == 'm') {
-            type = LengthTypeMM;
-        } else if (firstChar == 'i' && secondChar == 'n') {
-            type = LengthTypeIN;
-        } else if (isHTMLSpace<CharType>(firstChar) && isHTMLSpace<CharType>(secondChar)) {
-            type = LengthTypeNumber;
-        }
-    }
-
-    if (!skipOptionalSVGSpaces(ptr, end))
-        return type;
-
-    return LengthTypeUnknown;
-}
-
-} // namespace
-
 SVGLength::SVGLength(SVGLengthMode mode)
     : SVGPropertyBase(classType())
-    , m_valueInSpecifiedUnits(0)
+    , m_value(cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::UserUnits))
     , m_unitMode(static_cast<unsigned>(mode))
-    , m_unitType(LengthTypeNumber)
 {
     ASSERT(unitMode() == mode);
 }
 
 SVGLength::SVGLength(const SVGLength& o)
     : SVGPropertyBase(classType())
-    , m_valueInSpecifiedUnits(o.m_valueInSpecifiedUnits)
+    , m_value(o.m_value)
     , m_unitMode(o.m_unitMode)
-    , m_unitType(o.m_unitType)
 {
 }
 
+DEFINE_TRACE(SVGLength)
+{
+    visitor->trace(m_value);
+    SVGPropertyBase::trace(visitor);
+}
+
 PassRefPtrWillBeRawPtr<SVGLength> SVGLength::clone() const
 {
     return adoptRefWillBeNoop(new SVGLength(*this));
@@ -154,13 +69,11 @@
     RefPtrWillBeRawPtr<SVGLength> length = create();
 
     length->m_unitMode = m_unitMode;
-    length->m_unitType = m_unitType;
 
     TrackExceptionState exceptionState;
     length->setValueAsString(value, exceptionState);
     if (exceptionState.hadException()) {
-        length->m_unitType = LengthTypeNumber;
-        length->m_valueInSpecifiedUnits = 0;
+        length->m_value = CSSPrimitiveValue::create(0, CSSPrimitiveValue::UnitType::UserUnits);
     }
 
     return length.release();
@@ -168,116 +81,108 @@
 
 bool SVGLength::operator==(const SVGLength& other) const
 {
-    return m_unitMode == other.m_unitMode
-        && m_unitType == other.m_unitType
-        && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits;
+    return m_unitMode == other.m_unitMode && m_value == other.m_value;
 }
 
 float SVGLength::value(const SVGLengthContext& context) const
 {
-    return context.convertValueToUserUnits(m_valueInSpecifiedUnits, unitMode(), unitType());
+    return context.convertValueToUserUnits(
+        m_value->getFloatValue(), unitMode(), m_value->typeWithCalcResolved());
 }
 
 void SVGLength::setValue(float value, const SVGLengthContext& context)
 {
-    m_valueInSpecifiedUnits = context.convertValueFromUserUnits(value, unitMode(), unitType());
+    m_value = CSSPrimitiveValue::create(
+        context.convertValueFromUserUnits(value, unitMode(), m_value->typeWithCalcResolved()),
+        m_value->typeWithCalcResolved());
 }
 
-void SVGLength::setUnitType(SVGLengthType type)
+bool isSupportedCSSUnitType(CSSPrimitiveValue::UnitType type)
 {
-    ASSERT(type != LengthTypeUnknown && type <= LengthTypeCHS);
-    m_unitType = type;
+    return type != CSSPrimitiveValue::UnitType::Unknown
+        && (type <= CSSPrimitiveValue::UnitType::UserUnits
+            || type == CSSPrimitiveValue::UnitType::Chs
+            || type == CSSPrimitiveValue::UnitType::Rems);
+}
+
+void SVGLength::setUnitType(CSSPrimitiveValue::UnitType type)
+{
+    ASSERT(isSupportedCSSUnitType(type));
+    m_value = CSSPrimitiveValue::create(m_value->getFloatValue(), type);
 }
 
 float SVGLength::valueAsPercentage() const
 {
     // LengthTypePercentage is represented with 100% = 100.0. Good for accuracy but could eventually be changed.
-    if (m_unitType == LengthTypePercentage) {
+    if (m_value->isPercentage()) {
         // Note: This division is a source of floating point inaccuracy.
-        return m_valueInSpecifiedUnits / 100;
+        return m_value->getFloatValue() / 100;
     }
 
-    return m_valueInSpecifiedUnits;
+    return m_value->getFloatValue();
 }
 
 float SVGLength::valueAsPercentage100() const
 {
     // LengthTypePercentage is represented with 100% = 100.0. Good for accuracy but could eventually be changed.
-    if (m_unitType == LengthTypePercentage)
-        return m_valueInSpecifiedUnits;
+    if (m_value->isPercentage())
+        return m_value->getFloatValue();
 
-    return m_valueInSpecifiedUnits * 100;
+    return m_value->getFloatValue() * 100;
 }
 
 float SVGLength::scaleByPercentage(float input) const
 {
-    float result = input * m_valueInSpecifiedUnits;
-    if (m_unitType == LengthTypePercentage) {
+    float result = input * m_value->getFloatValue();
+    if (m_value->isPercentage()) {
         // Delaying division by 100 as long as possible since it introduces floating point errors.
         result = result / 100;
     }
     return result;
 }
 
-template<typename CharType>
-static bool parseValueInternal(const String& string, float& convertedNumber, SVGLengthType& type)
-{
-    const CharType* ptr = string.getCharacters<CharType>();
-    const CharType* end = ptr + string.length();
-
-    if (!parseNumber(ptr, end, convertedNumber, AllowLeadingWhitespace))
-        return false;
-
-    type = stringToLengthType(ptr, end);
-    ASSERT(ptr <= end);
-    if (type == LengthTypeUnknown)
-        return false;
-
-    return true;
-}
-
 void SVGLength::setValueAsString(const String& string, ExceptionState& exceptionState)
 {
     if (string.isEmpty()) {
-        m_unitType = LengthTypeNumber;
-        m_valueInSpecifiedUnits = 0;
+        m_value = cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::UserUnits);
         return;
     }
 
-    float convertedNumber = 0;
-    SVGLengthType type = LengthTypeUnknown;
-
-    bool success = string.is8Bit() ?
-        parseValueInternal<LChar>(string, convertedNumber, type) :
-        parseValueInternal<UChar>(string, convertedNumber, type);
-
-    if (!success) {
+    CSSParserContext svgParserContext(SVGAttributeMode, 0);
+    RefPtrWillBeRawPtr<CSSValue> parsed = CSSParser::parseSingleValue(CSSPropertyX, string, svgParserContext);
+    if (!parsed || !parsed->isPrimitiveValue()) {
         exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
         return;
     }
 
-    m_unitType = type;
-    m_valueInSpecifiedUnits = convertedNumber;
+    CSSPrimitiveValue* newValue = toCSSPrimitiveValue(parsed.get());
+    // TODO(fs): Enable calc for SVG lengths
+    if (newValue->isCalculated() || !isSupportedCSSUnitType(newValue->typeWithCalcResolved())) {
+        exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
+        return;
+    }
+
+    m_value = newValue;
 }
 
 String SVGLength::valueAsString() const
 {
-    return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(unitType());
+    return m_value->customCSSText();
 }
 
-void SVGLength::newValueSpecifiedUnits(SVGLengthType type, float value)
+void SVGLength::newValueSpecifiedUnits(CSSPrimitiveValue::UnitType type, float value)
 {
-    setUnitType(type);
-    m_valueInSpecifiedUnits = value;
+    m_value = CSSPrimitiveValue::create(value, type);
 }
 
-void SVGLength::convertToSpecifiedUnits(SVGLengthType type, const SVGLengthContext& context)
+void SVGLength::convertToSpecifiedUnits(CSSPrimitiveValue::UnitType type, const SVGLengthContext& context)
 {
-    ASSERT(type != LengthTypeUnknown && type <= LengthTypeCHS);
+    ASSERT(isSupportedCSSUnitType(type));
 
     float valueInUserUnits = value(context);
-    m_unitType = type;
-    setValue(valueInUserUnits, context);
+    m_value = CSSPrimitiveValue::create(
+        context.convertValueFromUserUnits(valueInUserUnits, unitMode(), type),
+        type);
 }
 
 SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedName& attrName)
@@ -323,7 +228,13 @@
     setValue(value(lengthContext) + toSVGLength(other)->value(lengthContext), lengthContext);
 }
 
-void SVGLength::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+void SVGLength::calculateAnimatedValue(SVGAnimationElement* animationElement,
+    float percentage,
+    unsigned repeatCount,
+    PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue,
+    PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue,
+    PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue,
+    SVGElement* contextElement)
 {
     RefPtrWillBeRawPtr<SVGLength> fromLength = toSVGLength(fromValue);
     RefPtrWillBeRawPtr<SVGLength> toLength = toSVGLength(toValue);
@@ -331,11 +242,14 @@
 
     SVGLengthContext lengthContext(contextElement);
     float animatedNumber = value(lengthContext);
-    animationElement->animateAdditiveNumber(percentage, repeatCount, fromLength->value(lengthContext), toLength->value(lengthContext), toAtEndOfDurationLength->value(lengthContext), animatedNumber);
+    animationElement->animateAdditiveNumber(percentage, repeatCount, fromLength->value(lengthContext),
+        toLength->value(lengthContext), toAtEndOfDurationLength->value(lengthContext), animatedNumber);
 
     ASSERT(unitMode() == lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
-    m_unitType = percentage < 0.5 ? fromLength->unitType() : toLength->unitType();
-    setValue(animatedNumber, lengthContext);
+
+    CSSPrimitiveValue::UnitType newUnit = percentage < 0.5 ? fromLength->typeWithCalcResolved() : toLength->typeWithCalcResolved();
+    animatedNumber = lengthContext.convertValueFromUserUnits(animatedNumber, unitMode(), newUnit);
+    m_value = CSSPrimitiveValue::create(animatedNumber, newUnit);
 }
 
 float SVGLength::calculateDistance(PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, SVGElement* contextElement)
diff --git a/third_party/WebKit/Source/core/svg/SVGLength.h b/third_party/WebKit/Source/core/svg/SVGLength.h
index 4662cbb5..171cd286 100644
--- a/third_party/WebKit/Source/core/svg/SVGLength.h
+++ b/third_party/WebKit/Source/core/svg/SVGLength.h
@@ -47,23 +47,17 @@
         return adoptRefWillBeNoop(new SVGLength(mode));
     }
 
+    DECLARE_VIRTUAL_TRACE();
+
     PassRefPtrWillBeRawPtr<SVGLength> clone() const;
     PassRefPtrWillBeRawPtr<SVGPropertyBase> cloneForAnimation(const String&) const override;
 
-    SVGLengthType unitType() const { return static_cast<SVGLengthType>(m_unitType); }
+    CSSPrimitiveValue::UnitType typeWithCalcResolved() const { return m_value->typeWithCalcResolved(); }
     CSSPrimitiveValue::UnitType cssUnitTypeQuirk() const
     {
-        if (m_unitType == LengthTypeNumber)
-            return CSSPrimitiveValue::UnitType::Pixels;
-
-        if (m_unitType == LengthTypeREMS)
-            return CSSPrimitiveValue::UnitType::Rems;
-        if (m_unitType == LengthTypeCHS)
-            return CSSPrimitiveValue::UnitType::Chs;
-
-        return static_cast<CSSPrimitiveValue::UnitType>(m_unitType);
+        return m_value->typeWithCalcResolved();
     }
-    void setUnitType(SVGLengthType);
+    void setUnitType(CSSPrimitiveValue::UnitType);
     SVGLengthMode unitMode() const { return static_cast<SVGLengthMode>(m_unitMode); }
 
     bool operator==(const SVGLength&) const;
@@ -72,8 +66,11 @@
     float value(const SVGLengthContext&) const;
     void setValue(float, const SVGLengthContext&);
 
-    float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; }
-    void setValueInSpecifiedUnits(float value) { m_valueInSpecifiedUnits = value; }
+    float valueInSpecifiedUnits() const { return m_value->getFloatValue(); }
+    void setValueInSpecifiedUnits(float value)
+    {
+        m_value = CSSPrimitiveValue::create(value, m_value->typeWithCalcResolved());
+    }
 
     // Resolves LengthTypePercentage into a normalized floating point number (full value is 1.0).
     float valueAsPercentage() const;
@@ -87,23 +84,23 @@
     String valueAsString() const override;
     void setValueAsString(const String&, ExceptionState&);
 
-    void newValueSpecifiedUnits(SVGLengthType, float valueInSpecifiedUnits);
-    void convertToSpecifiedUnits(SVGLengthType, const SVGLengthContext&);
+    void newValueSpecifiedUnits(CSSPrimitiveValue::UnitType, float valueInSpecifiedUnits);
+    void convertToSpecifiedUnits(CSSPrimitiveValue::UnitType, const SVGLengthContext&);
 
     // Helper functions
-    static inline bool isRelativeUnit(SVGLengthType unitType)
+    static inline bool isRelativeUnit(CSSPrimitiveValue::UnitType unitType)
     {
-        return unitType == LengthTypePercentage
-            || unitType == LengthTypeEMS
-            || unitType == LengthTypeEXS
-            || unitType == LengthTypeREMS
-            || unitType == LengthTypeCHS;
+        return unitType == CSSPrimitiveValue::UnitType::Percentage
+            || unitType == CSSPrimitiveValue::UnitType::Ems
+            || unitType == CSSPrimitiveValue::UnitType::Exs
+            || unitType == CSSPrimitiveValue::UnitType::Rems
+            || unitType == CSSPrimitiveValue::UnitType::Chs;
     }
-    inline bool isRelative() const { return isRelativeUnit(unitType()); }
+    inline bool isRelative() const { return isRelativeUnit(m_value->typeWithCalcResolved()); }
 
     bool isZero() const
     {
-        return !m_valueInSpecifiedUnits;
+        return m_value->getFloatValue() == 0;
     }
 
     static SVGLengthMode lengthModeForAnimatedLengthAttribute(const QualifiedName&);
@@ -118,9 +115,8 @@
     SVGLength(SVGLengthMode);
     SVGLength(const SVGLength&);
 
-    float m_valueInSpecifiedUnits;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_value;
     unsigned m_unitMode : 2;
-    unsigned m_unitType : 4;
 };
 
 DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGLength);
diff --git a/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp b/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
index 0c3b282..f553158 100644
--- a/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
@@ -183,48 +183,47 @@
     return floatValueForLength(length, dimension * zoom) / zoom;
 }
 
-float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, SVGLengthType fromUnit) const
+float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, CSSPrimitiveValue::UnitType fromUnit) const
 {
     float userUnits = value;
     switch (fromUnit) {
-    case LengthTypeUnknown:
-        return 0;
-    case LengthTypePX:
-    case LengthTypeNumber:
+    case CSSPrimitiveValue::UnitType::Pixels:
+    case CSSPrimitiveValue::UnitType::Number:
+    case CSSPrimitiveValue::UnitType::UserUnits:
         userUnits = value;
         break;
-    case LengthTypePercentage: {
+    case CSSPrimitiveValue::UnitType::Percentage: {
         FloatSize viewportSize;
         if (!determineViewport(viewportSize))
             return 0;
         userUnits = value * dimensionForLengthMode(mode, viewportSize) / 100;
         break;
     }
-    case LengthTypeEMS:
+    case CSSPrimitiveValue::UnitType::Ems:
         userUnits = convertValueFromEMSToUserUnits(computedStyleForLengthResolving(m_context), value);
         break;
-    case LengthTypeEXS:
+    case CSSPrimitiveValue::UnitType::Exs:
         userUnits = convertValueFromEXSToUserUnits(value);
         break;
-    case LengthTypeCM:
+    case CSSPrimitiveValue::UnitType::Centimeters:
         userUnits = value * cssPixelsPerCentimeter;
         break;
-    case LengthTypeMM:
+    case CSSPrimitiveValue::UnitType::Millimeters:
         userUnits = value * cssPixelsPerMillimeter;
         break;
-    case LengthTypeIN:
+    case CSSPrimitiveValue::UnitType::Inches:
         userUnits = value * cssPixelsPerInch;
         break;
-    case LengthTypePT:
+    case CSSPrimitiveValue::UnitType::Points:
         userUnits = value * cssPixelsPerPoint;
         break;
-    case LengthTypePC:
+    case CSSPrimitiveValue::UnitType::Picas:
         userUnits = value * cssPixelsPerPica;
         break;
-    case LengthTypeREMS:
+    case CSSPrimitiveValue::UnitType::Rems:
         userUnits = convertValueFromEMSToUserUnits(rootElementStyle(m_context), value);
         break;
-    case LengthTypeCHS:
+    case CSSPrimitiveValue::UnitType::Chs:
         userUnits = convertValueFromCHSToUserUnits(value);
         break;
     default:
@@ -238,14 +237,14 @@
     return CSSPrimitiveValue::clampToCSSLengthRange(userUnits);
 }
 
-float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mode, SVGLengthType toUnit) const
+float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mode, CSSPrimitiveValue::UnitType toUnit) const
 {
     switch (toUnit) {
-    case LengthTypeUnknown:
-        return 0;
-    case LengthTypeNumber:
+    case CSSPrimitiveValue::UnitType::Pixels:
+    case CSSPrimitiveValue::UnitType::Number:
+    case CSSPrimitiveValue::UnitType::UserUnits:
         return value;
-    case LengthTypePercentage: {
+    case CSSPrimitiveValue::UnitType::Percentage: {
         FloatSize viewportSize;
         if (!determineViewport(viewportSize))
             return 0;
@@ -256,26 +255,26 @@
         // Good for accuracy but could eventually be changed.
         return value * 100 / dimension;
     }
-    case LengthTypeEMS:
+    case CSSPrimitiveValue::UnitType::Ems:
         return convertValueFromUserUnitsToEMS(computedStyleForLengthResolving(m_context), value);
-    case LengthTypeEXS:
+    case CSSPrimitiveValue::UnitType::Exs:
         return convertValueFromUserUnitsToEXS(value);
-    case LengthTypeREMS:
+    case CSSPrimitiveValue::UnitType::Rems:
         return convertValueFromUserUnitsToEMS(rootElementStyle(m_context), value);
-    case LengthTypeCHS:
+    case CSSPrimitiveValue::UnitType::Chs:
         return convertValueFromUserUnitsToCHS(value);
-    case LengthTypePX:
-        return value;
-    case LengthTypeCM:
+    case CSSPrimitiveValue::UnitType::Centimeters:
         return value / cssPixelsPerCentimeter;
-    case LengthTypeMM:
+    case CSSPrimitiveValue::UnitType::Millimeters:
         return value / cssPixelsPerMillimeter;
-    case LengthTypeIN:
+    case CSSPrimitiveValue::UnitType::Inches:
         return value / cssPixelsPerInch;
-    case LengthTypePT:
+    case CSSPrimitiveValue::UnitType::Points:
         return value / cssPixelsPerPoint;
-    case LengthTypePC:
+    case CSSPrimitiveValue::UnitType::Picas:
         return value / cssPixelsPerPica;
+    default:
+        break;
     }
 
     ASSERT_NOT_REACHED();
diff --git a/third_party/WebKit/Source/core/svg/SVGLengthContext.h b/third_party/WebKit/Source/core/svg/SVGLengthContext.h
index 93a4064..ff73b761 100644
--- a/third_party/WebKit/Source/core/svg/SVGLengthContext.h
+++ b/third_party/WebKit/Source/core/svg/SVGLengthContext.h
@@ -20,6 +20,7 @@
 #ifndef SVGLengthContext_h
 #define SVGLengthContext_h
 
+#include "core/css/CSSPrimitiveValue.h"
 #include "core/svg/SVGUnitTypes.h"
 #include "platform/Length.h"
 #include "platform/geometry/FloatRect.h"
@@ -68,8 +69,8 @@
     static FloatPoint resolvePoint(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLength& x, const SVGLength& y);
     static float resolveLength(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLength&);
 
-    float convertValueToUserUnits(float, SVGLengthMode, SVGLengthType fromUnit) const;
-    float convertValueFromUserUnits(float, SVGLengthMode, SVGLengthType toUnit) const;
+    float convertValueToUserUnits(float, SVGLengthMode, CSSPrimitiveValue::UnitType fromUnit) const;
+    float convertValueFromUserUnits(float, SVGLengthMode, CSSPrimitiveValue::UnitType toUnit) const;
 
     float valueForLength(const UnzoomedLength&, SVGLengthMode = SVGLengthMode::Other) const;
     float valueForLength(const Length&, const ComputedStyle&, SVGLengthMode = SVGLengthMode::Other) const;
diff --git a/third_party/WebKit/Source/core/svg/SVGLengthList.cpp b/third_party/WebKit/Source/core/svg/SVGLengthList.cpp
index 46c57c91..60620ec7 100644
--- a/third_party/WebKit/Source/core/svg/SVGLengthList.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGLengthList.cpp
@@ -147,11 +147,11 @@
 
     for (size_t i = 0; i < toLengthListSize; ++i) {
         float animatedNumber = at(i)->value(lengthContext);
-        SVGLengthType unitType = toList->at(i)->unitType();
+        CSSPrimitiveValue::UnitType unitType = toList->at(i)->typeWithCalcResolved();
         float effectiveFrom = 0;
         if (fromLengthListSize) {
             if (percentage < 0.5)
-                unitType = fromList->at(i)->unitType();
+                unitType = fromList->at(i)->typeWithCalcResolved();
             effectiveFrom = fromList->at(i)->value(lengthContext);
         }
         float effectiveTo = toList->at(i)->value(lengthContext);
diff --git a/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp b/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp
index bf29952..7863e5c 100644
--- a/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp
@@ -40,10 +40,10 @@
 
 namespace {
 
-inline SVGLengthType toSVGLengthType(unsigned short type)
+inline bool isValidLengthUnit(unsigned short type)
 {
-    ASSERT(type >= LengthTypeUnknown && type <= LengthTypePC);
-    return static_cast<SVGLengthType>(type);
+    return type != static_cast<unsigned short>(CSSPrimitiveValue::UnitType::Unknown)
+        && type <= static_cast<unsigned short>(CSSPrimitiveValue::UnitType::Picas);
 }
 
 inline bool canResolveRelativeUnits(const SVGElement* contextElement)
@@ -51,11 +51,48 @@
     return contextElement && contextElement->inDocument();
 }
 
+inline CSSPrimitiveValue::UnitType toCSSUnitType(unsigned short type)
+{
+    ASSERT(isValidLengthUnit(type));
+    if (type == LengthTypeNumber)
+        return CSSPrimitiveValue::UnitType::UserUnits;
+    return static_cast<CSSPrimitiveValue::UnitType>(type);
+}
+
+inline SVGLengthType toSVGLengthType(CSSPrimitiveValue::UnitType type)
+{
+    switch (type) {
+    case CSSPrimitiveValue::UnitType::Unknown:
+        return LengthTypeUnknown;
+    case CSSPrimitiveValue::UnitType::UserUnits:
+        return LengthTypeNumber;
+    case CSSPrimitiveValue::UnitType::Percentage:
+        return LengthTypePercentage;
+    case CSSPrimitiveValue::UnitType::Ems:
+        return LengthTypeEMS;
+    case CSSPrimitiveValue::UnitType::Exs:
+        return LengthTypeEXS;
+    case CSSPrimitiveValue::UnitType::Pixels:
+        return LengthTypePX;
+    case CSSPrimitiveValue::UnitType::Centimeters:
+        return LengthTypeCM;
+    case CSSPrimitiveValue::UnitType::Millimeters:
+        return LengthTypeMM;
+    case CSSPrimitiveValue::UnitType::Inches:
+        return LengthTypeIN;
+    case CSSPrimitiveValue::UnitType::Points:
+        return LengthTypePT;
+    case CSSPrimitiveValue::UnitType::Picas:
+        return LengthTypePC;
+    default:
+        return LengthTypeUnknown;
+    }
+}
 } // namespace
 
 SVGLengthType SVGLengthTearOff::unitType()
 {
-    return hasExposedLengthUnit() ? target()->unitType() : LengthTypeUnknown;
+    return hasExposedLengthUnit() ? toSVGLengthType(target()->typeWithCalcResolved()) : LengthTypeUnknown;
 }
 
 SVGLengthMode SVGLengthTearOff::unitMode()
@@ -139,12 +176,12 @@
         return;
     }
 
-    if (unitType == LengthTypeUnknown || unitType > LengthTypePC) {
+    if (!isValidLengthUnit(unitType)) {
         exceptionState.throwDOMException(NotSupportedError, "Cannot set value with unknown or invalid units (" + String::number(unitType) + ").");
         return;
     }
 
-    target()->newValueSpecifiedUnits(toSVGLengthType(unitType), valueInSpecifiedUnits);
+    target()->newValueSpecifiedUnits(toCSSUnitType(unitType), valueInSpecifiedUnits);
     commitChange();
 }
 
@@ -155,19 +192,19 @@
         return;
     }
 
-    if (unitType == LengthTypeUnknown || unitType > LengthTypePC) {
+    if (!isValidLengthUnit(unitType)) {
         exceptionState.throwDOMException(NotSupportedError, "Cannot convert to unknown or invalid units (" + String::number(unitType) + ").");
         return;
     }
 
-    if ((target()->isRelative() || SVGLength::isRelativeUnit(toSVGLengthType(unitType)))
+    if ((target()->isRelative() || SVGLength::isRelativeUnit(toCSSUnitType(unitType)))
         && !canResolveRelativeUnits(contextElement())) {
         exceptionState.throwDOMException(NotSupportedError, "Could not resolve relative length.");
         return;
     }
 
     SVGLengthContext lengthContext(contextElement());
-    target()->convertToSpecifiedUnits(toSVGLengthType(unitType), lengthContext);
+    target()->convertToSpecifiedUnits(toCSSUnitType(unitType), lengthContext);
     commitChange();
 }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGLengthTearOff.h b/third_party/WebKit/Source/core/svg/SVGLengthTearOff.h
index 8714f7b..b7b7f75 100644
--- a/third_party/WebKit/Source/core/svg/SVGLengthTearOff.h
+++ b/third_party/WebKit/Source/core/svg/SVGLengthTearOff.h
@@ -32,6 +32,7 @@
 #define SVGLengthTearOff_h
 
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "core/css/CSSPrimitiveValue.h"
 #include "core/svg/SVGLength.h"
 #include "core/svg/properties/SVGPropertyTearOff.h"
 
@@ -71,7 +72,7 @@
     void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState&);
     void convertToSpecifiedUnits(unsigned short unitType, ExceptionState&);
 
-    bool hasExposedLengthUnit() { return target()->unitType() <= LengthTypePC; }
+    bool hasExposedLengthUnit() { return target()->typeWithCalcResolved() <= CSSPrimitiveValue::UnitType::UserUnits; }
 
 private:
     SVGLengthTearOff(PassRefPtrWillBeRawPtr<SVGLength>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName = QualifiedName::null());
diff --git a/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
index f1a5f4d..ebcd2f6c 100644
--- a/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
@@ -635,17 +635,17 @@
 
 bool SVGSVGElement::hasIntrinsicWidth() const
 {
-    return width()->currentValue()->unitType() != LengthTypePercentage;
+    return width()->currentValue()->typeWithCalcResolved() != CSSPrimitiveValue::UnitType::Percentage;
 }
 
 bool SVGSVGElement::hasIntrinsicHeight() const
 {
-    return height()->currentValue()->unitType() != LengthTypePercentage;
+    return height()->currentValue()->typeWithCalcResolved() != CSSPrimitiveValue::UnitType::Percentage;
 }
 
 Length SVGSVGElement::intrinsicWidth() const
 {
-    if (width()->currentValue()->unitType() == LengthTypePercentage)
+    if (width()->currentValue()->typeWithCalcResolved() == CSSPrimitiveValue::UnitType::Percentage)
         return Length(0, Fixed);
 
     SVGLengthContext lengthContext(this);
@@ -654,7 +654,7 @@
 
 Length SVGSVGElement::intrinsicHeight() const
 {
-    if (height()->currentValue()->unitType() == LengthTypePercentage)
+    if (height()->currentValue()->typeWithCalcResolved() == CSSPrimitiveValue::UnitType::Percentage)
         return Length(0, Fixed);
 
     SVGLengthContext lengthContext(this);
diff --git a/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp b/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
index 13c1283d..3844d534 100644
--- a/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
@@ -59,7 +59,7 @@
     {
         SVGTextContentElement* textContentElement = toSVGTextContentElement(contextElement());
         if (!textContentElement->textLengthIsSpecifiedByUser())
-            baseValue()->newValueSpecifiedUnits(LengthTypeNumber, textContentElement->getComputedTextLength());
+            baseValue()->newValueSpecifiedUnits(CSSPrimitiveValue::UnitType::Number, textContentElement->getComputedTextLength());
 
         return SVGAnimatedLength::baseVal();
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js b/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js
index b43471e..330bda28 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js
@@ -238,8 +238,8 @@
         var conditions = /** @type {?WebInspector.NetworkConditionsProfile} */ (item);
         var editor = this._createEditor();
         editor.control("title").value = conditions.title;
-        editor.control("throughput").value = conditions.value.throughput < 0 ? "" : String(conditions.value.throughput / (1024 / 8));
-        editor.control("latency").value = String(conditions.value.latency);
+        editor.control("throughput").value = conditions.value.throughput <= 0 ? "" : String(conditions.value.throughput / (1024 / 8));
+        editor.control("latency").value = conditions.value.latency ? String(conditions.value.latency) : "";
         return editor;
     },
 
diff --git a/third_party/WebKit/Source/devtools/front_end/devices/DevicesDialog.js b/third_party/WebKit/Source/devtools/front_end/devices/DevicesDialog.js
index 08332fcb..05fdade 100644
--- a/third_party/WebKit/Source/devtools/front_end/devices/DevicesDialog.js
+++ b/third_party/WebKit/Source/devtools/front_end/devices/DevicesDialog.js
@@ -35,7 +35,7 @@
             var dialog = new WebInspector.Dialog();
             dialog.addCloseButton();
             this._view.show(dialog.element);
-            dialog.setMaxSize(new Size(800, 600));
+            dialog.setMaxSize(new Size(700, 500));
             dialog.show();
             return true;
         }
diff --git a/third_party/WebKit/Source/devtools/front_end/devices/DevicesView.js b/third_party/WebKit/Source/devtools/front_end/devices/DevicesView.js
index cf223e4..09c72ba 100644
--- a/third_party/WebKit/Source/devtools/front_end/devices/DevicesView.js
+++ b/third_party/WebKit/Source/devtools/front_end/devices/DevicesView.js
@@ -30,7 +30,7 @@
     /** @type {!Map<string, !Element>} */
     this._listItemById = new Map();
 
-    this._viewContainer = hbox.createChild("div", "flex-auto");
+    this._viewContainer = hbox.createChild("div", "flex-auto vbox");
 
     var discoveryFooter = this.contentElement.createChild("div", "devices-footer");
     this._deviceCountSpan = discoveryFooter.createChild("span");
@@ -411,7 +411,7 @@
     this._device = null;
 }
 
-/** @typedef {!{browser: ?Adb.Browser, element: !Element, title: !Element, pages: !Element, pageSections: !Map<string, !WebInspector.DevicesView.PageSection>}} */
+/** @typedef {!{browser: ?Adb.Browser, element: !Element, title: !Element, pages: !Element, viewMore: !Element, newTab: !Element, pageSections: !Map<string, !WebInspector.DevicesView.PageSection>}} */
 WebInspector.DevicesView.BrowserSection;
 
 /** @typedef {!{page: ?Adb.Page, element: !Element, title: !Element, url: !Element, inspect: !Element}} */
@@ -465,8 +465,54 @@
         var element = createElementWithClass("div", "vbox flex-none");
         var topRow = element.createChild("div", "");
         var title = topRow.createChild("div", "device-browser-title");
+
+        var newTabRow = element.createChild("div", "device-browser-new-tab");
+        newTabRow.createChild("div", "").textContent = WebInspector.UIString("New tab:");
+        var newTabInput = newTabRow.createChild("input", "");
+        newTabInput.type = "text";
+        newTabInput.placeholder = WebInspector.UIString("Enter URL");
+        newTabInput.addEventListener("keydown", newTabKeyDown, false);
+        var newTabButton = createTextButton(WebInspector.UIString("Open"), openNewTab);
+        newTabRow.appendChild(newTabButton);
+
         var pages = element.createChild("div", "device-page-list vbox");
-        return {browser: null, element: element, title: title, pages: pages, pageSections: new Map()};
+
+        var viewMore = element.createChild("div", "device-view-more");
+        viewMore.addEventListener("click", viewMoreClick, false);
+        updateViewMoreTitle();
+
+        var section = {browser: null, element: element, title: title, pages: pages, viewMore: viewMore, newTab: newTabRow, pageSections: new Map()};
+        return section;
+
+        function viewMoreClick()
+        {
+            pages.classList.toggle("device-view-more-toggled");
+            updateViewMoreTitle();
+        }
+
+        function updateViewMoreTitle()
+        {
+            viewMore.textContent = pages.classList.contains("device-view-more-toggled") ? WebInspector.UIString("View less tabs\u2026") : WebInspector.UIString("View more tabs\u2026");
+        }
+
+        /**
+         * @param {!Event} event
+         */
+        function newTabKeyDown(event)
+        {
+            if (event.keyIdentifier === "Enter") {
+                event.consume(true);
+                openNewTab();
+            }
+        }
+
+        function openNewTab()
+        {
+            if (section.browser) {
+                InspectorFrontendHost.openRemotePage(section.browser.id, newTabInput.value.trim() || "about:blank");
+                newTabInput.value = "";
+            }
+        }
     },
 
     /**
@@ -493,7 +539,8 @@
             }
         }
 
-        for (var page of browser.pages) {
+        for (var index = 0; index < browser.pages.length; ++index) {
+            var page = browser.pages[index];
             var pageSection = section.pageSections.get(page.id);
             if (!pageSection) {
                 pageSection = this._createPageSection();
@@ -501,8 +548,15 @@
                 section.pages.appendChild(pageSection.element);
             }
             this._updatePageSection(pageSection, page);
+            if (!index && section.pages.firstChild !== pageSection.element)
+                section.pages.insertBefore(pageSection.element, section.pages.firstChild);
         }
 
+        var kViewMoreCount = 3;
+        for (var index = 0, element = section.pages.firstChild; element; element = element.nextSibling, ++index)
+            element.classList.toggle("device-view-more-page", index >= kViewMoreCount);
+        section.viewMore.classList.toggle("device-needs-view-more", browser.pages.length > kViewMoreCount);
+        section.newTab.classList.toggle("hidden", !browser.adbBrowserChromeVersion);
         section.browser = browser;
     },
 
@@ -512,32 +566,34 @@
     _createPageSection: function()
     {
         var element = createElementWithClass("div", "vbox");
-        var title = element.createChild("div", "device-page-title");
+
+        var titleRow = element.createChild("div", "device-page-title-row");
+        var title = titleRow.createChild("div", "device-page-title");
+        var inspect = createTextButton(WebInspector.UIString("Inspect"), doAction.bind(null, "inspect"), "device-inspect-button");
+        titleRow.appendChild(inspect);
+
+        var toolbar = new WebInspector.Toolbar();
+        toolbar.appendToolbarItem(new WebInspector.ToolbarMenuButton("", "menu-toolbar-item", appendActions));
+        titleRow.appendChild(toolbar.element);
+
         var url = element.createChild("div", "device-page-url");
-        var actions = element.createChild("div", "device-page-actions hbox");
-        var section = /** @type {!WebInspector.DevicesView.PageSection} */ ({page: null, element: element, title: title, url: url});
-        section.inspect = this._createAction(actions, WebInspector.UIString("inspect"), "inspect", section);
-        this._createAction(actions, WebInspector.UIString("reload"), "reload", section);
-        this._createAction(actions, WebInspector.UIString("activate"), "activate", section);
-        this._createAction(actions, WebInspector.UIString("close"), "close", section);
+        var section = {page: null, element: element, title: title, url: url, inspect: inspect};
         return section;
-    },
 
-    /**
-     * @param {!Element} container
-     * @param {string} title
-     * @param {string} action
-     * @param {!WebInspector.DevicesView.PageSection} section
-     * @return {!Element}
-     */
-    _createAction: function(container, title, action, section)
-    {
-        var element = container.createChild("div", "link");
-        element.textContent = title;
-        element.addEventListener("click", onClick, false);
-        return element;
+        /**
+         * @param {!WebInspector.ContextMenu} contextMenu
+         */
+        function appendActions(contextMenu)
+        {
+            contextMenu.appendItem(WebInspector.UIString("Reload"), doAction.bind(null, "reload"));
+            contextMenu.appendItem(WebInspector.UIString("Focus"), doAction.bind(null, "activate"));
+            contextMenu.appendItem(WebInspector.UIString("Close"), doAction.bind(null, "close"));
+        }
 
-        function onClick()
+        /**
+         * @param {string} action
+         */
+        function doAction(action)
         {
             if (section.page)
                 InspectorFrontendHost.performActionOnRemotePage(section.page.id, action);
@@ -550,8 +606,10 @@
      */
     _updatePageSection: function(section, page)
     {
-        if (!section.page || section.page.name !== page.name)
+        if (!section.page || section.page.name !== page.name) {
             section.title.textContent = page.name;
+            section.title.title = page.name;
+        }
         if (!section.page || section.page.url !== page.url) {
             section.url.textContent = "";
             section.url.appendChild(WebInspector.linkifyURLAsNode(page.url, undefined, undefined, true));
diff --git a/third_party/WebKit/Source/devtools/front_end/devices/devicesView.css b/third_party/WebKit/Source/devtools/front_end/devices/devicesView.css
index 093f4ad..a34ec956 100644
--- a/third_party/WebKit/Source/devtools/front_end/devices/devicesView.css
+++ b/third_party/WebKit/Source/devtools/front_end/devices/devicesView.css
@@ -181,6 +181,7 @@
 .device-view {
     overflow: auto;
     -webkit-user-select: text;
+    flex: auto;
 }
 
 .device-text-row {
@@ -196,6 +197,7 @@
 .device-browser-list {
     flex: auto;
     overflow: auto;
+    padding-right: 10px;
 }
 
 .device-browser-list > div {
@@ -203,32 +205,62 @@
 }
 
 .device-browser-title {
-    font-size: larger;
+    font-size: 16px;
+}
+
+.device-browser-new-tab {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin: 10px 0 0 10px;
+}
+
+.device-browser-new-tab > div {
+    font-size: 13px;
+}
+
+.device-browser-new-tab > input {
+    margin: 0 10px;
 }
 
 .device-page-list {
-    margin-top: 10px;
+    margin: 10px 0 0 10px;
     overflow-x: auto;
     align-items: stretch;
     flex: none;
 }
 
 .device-page-list > div {
-    padding: 5px;
-    overflow: visible;
     flex: none;
+    padding: 5px 0;
 }
 
-.device-page-list > div:hover {
-    background-color: #f3f3f3;
+.device-page-list:not(.device-view-more-toggled) > div.device-view-more-page {
+    display: none;
 }
 
-.device-page-actions {
-    justify-content: flex-start;
+.device-page-title-row {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
 }
 
-.device-page-actions > .link {
-    margin-right: 8px;
+.device-page-title {
+    font-size: 15px;
+    flex: auto;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+.device-page-title-row .toolbar {
+    margin-left: 3px;
+    padding: 0;
+    border-radius: 3px;
+}
+
+.device-page-title-row .toolbar:hover {
+    background-color: hsl(0, 0%, 90%);
 }
 
 .device-page-url {
@@ -236,9 +268,18 @@
 }
 
 .device-page-url a {
-    display: block;
     color: #777;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-    overflow: hidden;
+    word-break: break-all;
 }
+
+.device-view-more {
+    cursor: pointer;
+    text-decoration: underline;
+    color: rgb(17, 85, 204);
+    margin: 5px 0 0 10px;
+    display: none;
+}
+
+.device-view-more.device-needs-view-more  {
+    display: block;
+}
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/devtools.js b/third_party/WebKit/Source/devtools/front_end/devtools.js
index 000b533fa..efc0cce 100644
--- a/third_party/WebKit/Source/devtools/front_end/devtools.js
+++ b/third_party/WebKit/Source/devtools/front_end/devtools.js
@@ -694,6 +694,16 @@
 
     /**
      * @override
+     * @param {string} browserId
+     * @param {string} url
+     */
+    openRemotePage: function(browserId, url)
+    {
+        DevToolsAPI.sendMessageToEmbedder("openRemotePage", [browserId, url], null);
+    },
+
+    /**
+     * @override
      * @param {number} x
      * @param {number} y
      * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/ResponsiveDesignView.js b/third_party/WebKit/Source/devtools/front_end/emulation/ResponsiveDesignView.js
index ec00cf5..9768135 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/ResponsiveDesignView.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/ResponsiveDesignView.js
@@ -512,6 +512,7 @@
             this._pageScaleContainer.style.top = cssCanvasOffset;
             this._mediaInspectorContainer.style.left = cssRulerWidth;
             this._mediaInspectorContainer.style.marginTop = cssRulerHeight;
+            this._warningInfobar.element.style.left = cssRulerWidth;
         }
 
         var cssWidth = (this._dipWidth ? this._dipWidth : availableDip.width) / zoomFactor;
diff --git a/third_party/WebKit/Source/devtools/front_end/host/InspectorFrontendHost.js b/third_party/WebKit/Source/devtools/front_end/host/InspectorFrontendHost.js
index 7149d3c..5fc21beb 100644
--- a/third_party/WebKit/Source/devtools/front_end/host/InspectorFrontendHost.js
+++ b/third_party/WebKit/Source/devtools/front_end/host/InspectorFrontendHost.js
@@ -410,6 +410,15 @@
 
     /**
      * @override
+     * @param {string} browserId
+     * @param {string} url
+     */
+    openRemotePage: function(browserId, url)
+    {
+    },
+
+    /**
+     * @override
      * @param {number} x
      * @param {number} y
      * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items
diff --git a/third_party/WebKit/Source/devtools/front_end/host/InspectorFrontendHostAPI.js b/third_party/WebKit/Source/devtools/front_end/host/InspectorFrontendHostAPI.js
index 4b38146..5821f4c 100644
--- a/third_party/WebKit/Source/devtools/front_end/host/InspectorFrontendHostAPI.js
+++ b/third_party/WebKit/Source/devtools/front_end/host/InspectorFrontendHostAPI.js
@@ -249,6 +249,12 @@
     performActionOnRemotePage: function(pageId, action) { },
 
     /**
+     * @param {string} browserId
+     * @param {string} url
+     */
+    openRemotePage: function(browserId, url) { },
+
+    /**
      * @param {string} origin
      * @param {string} script
      */
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
index 1588001..6bead516 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
@@ -1049,12 +1049,11 @@
     },
 
     /**
-      * @param {!WebInspector.NetworkLogView.FilterType} filterType
-      * @param {string} filterValue
+      * @param {string} filterString
       */
-    setTextFilterValue: function(filterType, filterValue)
+    setTextFilterValue: function(filterString)
     {
-        this._textFilterUI.setValue(filterType + ":" + filterValue);
+        this._textFilterUI.setValue(filterString);
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
index 0d73753..1375aaf5 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
@@ -637,13 +637,15 @@
 }
 
 /**
-  * @param {!WebInspector.NetworkLogView.FilterType} filterType
-  * @param {string} filterValue
+  * @param {!Array<{filterType: !WebInspector.NetworkLogView.FilterType, filterValue: string}>} filters
   */
-WebInspector.NetworkPanel.revealAndFilter = function(filterType, filterValue)
+WebInspector.NetworkPanel.revealAndFilter = function(filters)
 {
     var panel = WebInspector.NetworkPanel._instance();
-    panel._networkLogView.setTextFilterValue(filterType, filterValue);
+    var filterString = '';
+    for (var filter of filters)
+        filterString += filter.filterType + ':' + filter.filterValue + ' ';
+    panel._networkLogView.setTextFilterValue(filterString);
     WebInspector.inspectorView.setCurrentPanel(panel);
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js b/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
index aee0d65..152bceb 100644
--- a/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
@@ -592,7 +592,12 @@
         function showDisplayedMixedContentInNetworkPanel(e)
         {
             e.consume();
-            WebInspector.NetworkPanel.revealAndFilter(WebInspector.NetworkLogView.FilterType.MixedContent, WebInspector.NetworkLogView.MixedContentFilterValues.Displayed);
+            WebInspector.NetworkPanel.revealAndFilter([
+                {
+                    filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
+                    filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.Displayed
+                }
+            ]);
         }
 
         /**
@@ -601,7 +606,12 @@
         function showBlockOverriddenMixedContentInNetworkPanel(e)
         {
             e.consume();
-            WebInspector.NetworkPanel.revealAndFilter(WebInspector.NetworkLogView.FilterType.MixedContent, WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden);
+            WebInspector.NetworkPanel.revealAndFilter([
+                {
+                    filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
+                    filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden
+                }
+            ]);
         }
 
          /**
@@ -610,7 +620,12 @@
         function showBlockedMixedContentInNetworkPanel(e)
         {
             e.consume();
-            WebInspector.NetworkPanel.revealAndFilter(WebInspector.NetworkLogView.FilterType.MixedContent, WebInspector.NetworkLogView.MixedContentFilterValues.Blocked);
+            WebInspector.NetworkPanel.revealAndFilter([
+                {
+                    filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
+                    filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.Blocked
+                }
+            ]);
         }
     },
 
@@ -668,6 +683,24 @@
     this._originLockIcon.classList.add("security-property-" + originState.securityState);
     // TODO(lgarron): Highlight the origin scheme. https://crbug.com/523589
     originDisplay.createChild("span", "origin").textContent = origin;
+    var originNetworkLink = originDisplay.createChild("div", "link");
+    originNetworkLink.textContent = WebInspector.UIString("View requests in Network Panel");
+    function showOriginRequestsInNetworkPanel()
+    {
+        var parsedURL = new WebInspector.ParsedURL(origin);
+        WebInspector.NetworkPanel.revealAndFilter([
+            {
+                filterType: WebInspector.NetworkLogView.FilterType.Domain,
+                filterValue: parsedURL.host
+            },
+            {
+                filterType: WebInspector.NetworkLogView.FilterType.Scheme,
+                filterValue: parsedURL.scheme
+            }
+        ]);
+    }
+    originNetworkLink.addEventListener("click", showOriginRequestsInNetworkPanel, false);
+
 
     if (originState.securityDetails) {
         var connectionSection = this.element.createChild("div", "origin-view-section");
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js b/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js
index 1fbab52..a8e2b7f 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js
@@ -39,7 +39,7 @@
     WebInspector.VBox.call(this);
     this.element.classList.add("layers-3d-view");
     this._failBanner = new WebInspector.VBox();
-    this._failBanner.element.classList.add("fail-banner", "fill");
+    this._failBanner.element.classList.add("banner");
     this._failBanner.element.createTextChild(WebInspector.UIString("Layer information is not yet available."));
 
     this._layerViewHost = layerViewHost;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/PaintProfilerView.js b/third_party/WebKit/Source/devtools/front_end/timeline/PaintProfilerView.js
index fd7a0933..a9a592b 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/PaintProfilerView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/PaintProfilerView.js
@@ -38,7 +38,7 @@
     WebInspector.HBox.call(this);
     this.element.classList.add("paint-profiler-overview", "hbox");
     this._canvasContainer = this.element.createChild("div", "paint-profiler-canvas-container");
-    this._progressBanner = this.element.createChild("div", "fill progress-banner hidden");
+    this._progressBanner = this.element.createChild("div", "banner hidden");
     this._progressBanner.textContent = WebInspector.UIString("Profiling\u2026");
     this._pieChart = new WebInspector.PieChart(55, this._formatPieChartTime.bind(this), true);
     this._pieChart.element.classList.add("paint-profiler-pie-chart");
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
index 4629d14..cd72128 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
@@ -1013,9 +1013,11 @@
 
         if (jsSamples && jsSamples.length)
             events = events.mergeOrdered(jsSamples, WebInspector.TracingModel.Event.orderedCompareStartTime);
-        var jsFrameEvents = WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents(events);
-        if (jsFrameEvents && jsFrameEvents.length)
-            events = jsFrameEvents.mergeOrdered(events, WebInspector.TracingModel.Event.orderedCompareStartTime);
+        if (jsSamples || events.some(function(e) { return e.name === WebInspector.TimelineModel.RecordType.JSSample; })) {
+            var jsFrameEvents = WebInspector.TimelineJSProfileProcessor.generateJSFrameEvents(events);
+            if (jsFrameEvents && jsFrameEvents.length)
+                events = jsFrameEvents.mergeOrdered(events, WebInspector.TracingModel.Event.orderedCompareStartTime);
+        }
 
         var threadEvents;
         var threadAsyncEventsByGroup;
@@ -1485,7 +1487,7 @@
  * @param {number} startTime
  * @param {number} endTime
  * @param {!Array<!WebInspector.TimelineModel.Filter>} filters
- * @param {function(!WebInspector.TracingModel.Event):(string|symbol)} eventIdCallback
+ * @param {function(!WebInspector.TracingModel.Event):(string|symbol)=} eventIdCallback
  * @return {!WebInspector.TimelineModel.ProfileTreeNode}
  */
 WebInspector.TimelineModel.buildTopDownTree = function(events, startTime, endTime, filters, eventIdCallback)
@@ -1496,6 +1498,7 @@
     root.totalTime = initialTime;
     root.selfTime = initialTime;
     root.name = WebInspector.UIString("Top-Down Chart");
+    root.children = /** @type {!Map<string, !WebInspector.TimelineModel.ProfileTreeNode>} */ (new Map());
     var parent = root;
 
     /**
@@ -1518,8 +1521,8 @@
     {
         if (!filter(e))
             return;
-        var time = Math.min(endTime, e.endTime) - Math.max(startTime, e.startTime);
-        var id = eventIdCallback(e);
+        var time = e.endTime ? Math.min(endTime, e.endTime) - Math.max(startTime, e.startTime) : 0;
+        var id = eventIdCallback ? eventIdCallback(e) : Symbol("uniqueEventId");
         if (!parent.children)
             parent.children = /** @type {!Map<string,!WebInspector.TimelineModel.ProfileTreeNode>} */ (new Map());
         var node = parent.children.get(id);
@@ -1540,7 +1543,8 @@
             console.log("Error: Negative self of " + parent.selfTime, e);
             parent.selfTime = 0;
         }
-        parent = node;
+        if (e.endTime)
+            parent = node;
     }
 
     /**
@@ -1553,7 +1557,8 @@
         parent = parent.parent;
     }
 
-    WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, undefined, startTime, endTime);
+    var instantEventCallback = eventIdCallback ? undefined : onStartEvent; // Ignore instant events when aggregating.
+    WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, instantEventCallback, startTime, endTime);
     root.totalTime -= root.selfTime;
     root.selfTime = 0;
     return root;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
index 146f05e2..e7f7565 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -377,9 +377,9 @@
                                                                              this._captureNetworkSetting,
                                                                              WebInspector.UIString("Capture network requests information")));
         }
-        this._enableJSSamplingSettingSetting = WebInspector.settings.createSetting("timelineEnableJSSampling", true);
+        this._enableJSSamplingSetting = WebInspector.settings.createSetting("timelineEnableJSSampling", true);
         this._panelToolbar.appendToolbarItem(this._createSettingCheckbox(WebInspector.UIString("JS Profile"),
-                                                                         this._enableJSSamplingSettingSetting,
+                                                                         this._enableJSSamplingSetting,
                                                                          WebInspector.UIString("Capture JavaScript stacks with sampling profiler. (Has performance overhead)")));
 
         this._captureMemorySetting = WebInspector.settings.createSetting("timelineCaptureMemory", false);
@@ -670,7 +670,7 @@
         this._updateStatus(WebInspector.UIString("Initializing recording\u2026"));
 
         this._autoRecordGeneration = userInitiated ? null : Symbol("Generation");
-        this._model.startRecording(true, this._enableJSSamplingSettingSetting.get(), this._captureMemorySetting.get(), this._captureLayersAndPicturesSetting.get(), this._captureFilmStripSetting && this._captureFilmStripSetting.get());
+        this._model.startRecording(true, this._enableJSSamplingSetting.get(), this._captureMemorySetting.get(), this._captureLayersAndPicturesSetting.get(), this._captureFilmStripSetting && this._captureFilmStripSetting.get());
 
         for (var i = 0; i < this._overviewControls.length; ++i)
             this._overviewControls[i].timelineStarted();
@@ -800,7 +800,7 @@
         var recordNode = encloseWithTag("b", WebInspector.shortcutRegistry.shortcutDescriptorsForAction("timeline.toggle-recording")[0].name);
         var reloadNode = encloseWithTag("b", WebInspector.shortcutRegistry.shortcutDescriptorsForAction("main.reload")[0].name);
         var navigateNode = encloseWithTag("b", WebInspector.UIString("WASD"));
-        var hintText = createElementWithClass("div", "recording-hint");
+        var hintText = createElementWithClass("div");
         hintText.appendChild(WebInspector.formatLocalized(WebInspector.UIString("To capture a new timeline, click the record toolbar button or hit %s."), [recordNode], null));
         hintText.createChild("br");
         hintText.appendChild(WebInspector.formatLocalized(WebInspector.UIString("To evaluate page load performance, hit %s to record the reload."), [reloadNode], null));
@@ -809,7 +809,7 @@
         hintText.createChild("br");
         hintText.appendChild(WebInspector.formatLocalized(WebInspector.UIString("Then, zoom and pan the timeline with the mousewheel and %s keys."), [navigateNode], null));
         this._hideRecordingHelpMessage();
-        this._helpMessageElement = this._searchableView.element.createChild("div", "timeline-status-pane fill");
+        this._helpMessageElement = this._searchableView.element.createChild("div", "banner timeline-status-pane");
         this._helpMessageElement.appendChild(hintText);
     },
 
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
index 4d0aa38..3ed893b 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
@@ -26,15 +26,43 @@
         new WebInspector.ExcludeTopLevelFilter()
     ];
 
-    this._populateToolbar();
-
     var columns = [];
     this._populateColumns(columns);
     this._dataGrid = new WebInspector.SortableDataGrid(columns);
     this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortingChanged, this);
     var dataGridContainerWidget = new WebInspector.DataGridContainerWidget();
+    this._populateToolbar(dataGridContainerWidget.element);
     dataGridContainerWidget.appendDataGrid(this._dataGrid);
-    dataGridContainerWidget.show(this.element);
+
+    this._splitWidget = new WebInspector.SplitWidget(true, true, "timelineTreeViewDetailsSplitWidget");
+    this._splitWidget.show(this.element);
+    this._splitWidget.setMainWidget(dataGridContainerWidget);
+    /** @type {?WebInspector.TimelineModel.ProfileTreeNode} */
+    this._lastSelectedNode = null;
+
+    if (Runtime.experiments.isEnabled("timelineEventsTreeView")) {
+        this._detailsView = new WebInspector.VBox();
+        this._detailsView.element.classList.add("timeline-tree-view-details");
+        this._splitWidget.setSidebarWidget(this._detailsView);
+        this._showBannerInDetails();
+        this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, onSelectionChanged, this);
+    } else {
+        this._splitWidget.hideSidebar(false);
+    }
+
+    /**
+     * @this {WebInspector.TimelineTreeView}
+     */
+    function onSelectionChanged()
+    {
+        var selectedNode = this._dataGrid.selectedNode ? /** @type {!WebInspector.TimelineTreeView.GridNode} */ (this._dataGrid.selectedNode)._profileNode : null;
+        if (selectedNode === this._lastSelectedNode)
+            return;
+        this._lastSelectedNode = selectedNode;
+        this._detailsView.element.removeChildren();
+        if (!selectedNode || !this._showDetailsForNode(selectedNode))
+            this._showBannerInDetails();
+    }
 }
 
 WebInspector.TimelineTreeView.prototype = {
@@ -57,7 +85,10 @@
         this._refreshTree();
     },
 
-    _populateToolbar: function() { },
+    /**
+     * @param {!Element} parent
+     */
+    _populateToolbar: function(parent) { },
 
     /**
      * @param {?string} scriptId
@@ -175,6 +206,21 @@
         }
     },
 
+    _showBannerInDetails: function()
+    {
+        var banner = this._detailsView.element.createChild("div", "banner");
+        banner.createTextChild("No details are available for current selection.");
+    },
+
+    /**
+     * @param {!WebInspector.TimelineModel.ProfileTreeNode} node
+     * @return {boolean}
+     */
+    _showDetailsForNode: function(node)
+    {
+        return false;
+    },
+
     __proto__: WebInspector.VBox.prototype
 }
 
@@ -226,6 +272,8 @@
     return frame && frame["url"] || null;
 }
 
+WebInspector.TimelineTreeView._gridNodeSymbol = Symbol("gridNode");
+
 /**
  * @constructor
  * @extends {WebInspector.SortableDataGridNode}
@@ -259,6 +307,8 @@
     this._treeView = treeView;
     this._totalTime = grandTotalTime;
     this._maxTimes = { self: maxSelfTime, total: maxTotalTime };
+    profileNode[WebInspector.TimelineTreeView._gridNodeSymbol] = this;
+
     var selfTime = profileNode.selfTime;
     var selfPercent = selfTime / grandTotalTime * 100;
     var totalTime = profileNode.totalTime;
@@ -403,10 +453,11 @@
 WebInspector.AggregatedTimelineTreeView.prototype = {
     /**
      * @override
+     * @param {!Element} parent
      */
-    _populateToolbar: function()
+    _populateToolbar: function(parent)
     {
-        var panelToolbar = new WebInspector.Toolbar(this.element);
+        var panelToolbar = new WebInspector.Toolbar(parent);
         this._groupByCombobox = new WebInspector.ToolbarComboBox(this._onGroupByChanged.bind(this));
         /**
          * @param {string} name
@@ -639,25 +690,59 @@
 WebInspector.EventsTimelineTreeView.prototype = {
     /**
      * @override
-     * @return {!WebInspector.TimelineModel.ProfileTreeNode}
+     * @param {!WebInspector.TimelineSelection} selection
      */
-    _buildTree: function()
+    updateContents: function(selection)
     {
-        return WebInspector.TimelineModel.buildTopDownTree(this._model.mainThreadEvents(), this._startTime, this._endTime, this._filters, uniqueSymbol);
-
-        /**
-         * @return {symbol}
-         */
-        function uniqueSymbol()
-        {
-            return Symbol("eventId");
-        }
+        WebInspector.TimelineTreeView.prototype.updateContents.call(this, selection);
+        if (selection.type() !== WebInspector.TimelineSelection.Type.TraceEvent)
+            return;
+        var pathToSelectedEvent = this._findPathToNodeWithEvent(/** @type {!WebInspector.TracingModel.Event} */ (selection.object()));
+        if (!pathToSelectedEvent)
+            return;
+        for (var i = 1; i < pathToSelectedEvent.length - 1; ++i)
+            pathToSelectedEvent[i][WebInspector.TimelineTreeView._gridNodeSymbol].expand();
+        pathToSelectedEvent.peekLast()[WebInspector.TimelineTreeView._gridNodeSymbol].revealAndSelect();
     },
 
     /**
      * @override
+     * @return {!WebInspector.TimelineModel.ProfileTreeNode}
      */
-    _populateToolbar: function() { },
+    _buildTree: function()
+    {
+        this._currentTree = WebInspector.TimelineModel.buildTopDownTree(this._model.mainThreadEvents(), this._startTime, this._endTime, this._filters);
+        return this._currentTree;
+    },
+
+    /**
+     * @param {!WebInspector.TracingModel.Event} event
+     * @return {?Array<!WebInspector.TimelineModel.ProfileTreeNode>}
+     */
+    _findPathToNodeWithEvent: function(event)
+    {
+        var stack = [this._currentTree];
+        var iterators = [this._currentTree.children.values()];
+
+        while (stack.length) {
+            var iterator = iterators.peekLast().next();
+            if (iterator.done) {
+                stack.pop();
+                iterators.pop();
+                continue;
+            }
+            var child = /** @type {!WebInspector.TimelineModel.ProfileTreeNode} */ (iterator.value);
+            if (child.event === event) {
+                stack.push(child);
+                return stack;
+            }
+            if (child.children) {
+                stack.push(child);
+                iterators.push(child.children.values());
+            }
+        }
+        return null;
+    },
 
     /**
      * @override
@@ -669,5 +754,28 @@
         WebInspector.TimelineTreeView.prototype._populateColumns.call(this, columns);
     },
 
+    /**
+     * @override
+     * @param {!WebInspector.TimelineModel.ProfileTreeNode} node
+     * @return {boolean}
+     */
+    _showDetailsForNode: function(node)
+    {
+        var traceEvent = node.event;
+        if (!traceEvent)
+            return false;
+        WebInspector.TimelineUIUtils.buildTraceEventDetails(traceEvent, this._model, this._linkifier, showDetails.bind(this));
+        return true;
+
+        /**
+         * @param {!DocumentFragment} fragment
+         * @this {WebInspector.EventsTimelineTreeView}
+         */
+        function showDetails(fragment)
+        {
+            this._detailsView.element.appendChild(fragment);
+        }
+    },
+
     __proto__: WebInspector.TimelineTreeView.prototype
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
index 949c51b8..94e8e8b 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/timelinePanel.css
@@ -37,6 +37,28 @@
     border-bottom: 1px solid rgb(140, 140, 140);
 }
 
+.panel.timeline .banner,
+.panel.layers .banner {
+    color: #777;
+    background-color: white;
+    font-size: 14px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    text-align: center;
+    padding: 20px;
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+}
+
+.panel.timeline .banner a,
+.panel.layers .banner a {
+    color: inherit;
+}
+
 #timeline-overview-panel .timeline-graph-bar {
     pointer-events: none;
 }
@@ -760,22 +782,8 @@
     overflow: hidden;
 }
 
-.timeline-status-pane {
-    color: #777;
-    background-color: white;
-    font-size: 30px;
-    z-index: 500;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    text-align: center;
-    padding: 0 20px;
-    overflow: auto;
-}
-
-.timeline-status-pane .recording-hint {
-    font-size: 14px;
-    text-align: left;
+.timeline-status-pane.banner {
+    text-align: left !important;
 }
 
 .layer-tree,
@@ -792,30 +800,11 @@
     flex: 1 1;
 }
 
-.layers-3d-view .fail-banner {
-    position: absolute;
-    font-size: 24px;
-    color: rgb(75%, 75%, 75%);
-    font-weight: bold;
-    padding: 10px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-}
-
-.layers-3d-view .fail-banner a {
-    color: inherit;
-}
-
 .transform-control-panel {
     white-space: nowrap;
     flex: none;
 }
 
-.layer-details-view .empty-view {
-    font-size: 16px;
-}
-
 .layer-details-view table td {
     padding-left: 8px;
 }
@@ -828,14 +817,8 @@
     background-color: rgba(100, 100, 100, 0.2);
 }
 
-.paint-profiler-overview .progress-banner {
-    color: #777;
-    background-color: rgba(255, 255, 255, 0.8);
-    font-size: 20px;
+.paint-profiler-overview .banner {
     z-index: 500;
-    display: flex;
-    justify-content: center;
-    align-items: center;
 }
 
 .paint-profiler-canvas-container {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js b/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
index 761adab6..856b8e3 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
@@ -40,7 +40,7 @@
     this._element = createElementWithClass("div", "filter-bar hidden");
 
     this._filterButton = new WebInspector.ToolbarButton(WebInspector.UIString("Filter"), "filter-toolbar-item", 3);
-    this._filterButton.element.addEventListener("click", this._handleFilterButtonClick.bind(this), false);
+    this._filterButton.addEventListener("click", this._handleFilterButtonClick, this);
 
     this._filters = [];
 
@@ -123,7 +123,7 @@
     },
 
     /**
-     * @param {!Event} event
+     * @param {!WebInspector.Event} event
      */
     _handleFilterButtonClick: function(event)
     {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/timelineGrid.css b/third_party/WebKit/Source/devtools/front_end/ui_lazy/timelineGrid.css
index 3d952f4..db0da22 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/timelineGrid.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/timelineGrid.css
@@ -67,7 +67,7 @@
 }
 
 .timeline-curtain-left, .timeline-curtain-right {
-    background-color: hsla(0, 0%, 80%, 0.3);
+    background-color: hsla(0, 0%, 80%, 0.5);
     position: absolute;
     top: 0;
     height: 100%;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp
index 0522b84..b6bafbb 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp
@@ -10,6 +10,7 @@
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
+#include "platform/audio/AudioUtilities.h"
 
 #if DEBUG_AUDIONODE_REFERENCES
 #include <stdio.h>
@@ -41,6 +42,18 @@
     AudioContext* audioContext = new AudioContext(document);
     audioContext->suspendIfNeeded();
 
+    if (!AudioUtilities::isValidAudioBufferSampleRate(audioContext->sampleRate())) {
+        exceptionState.throwDOMException(
+            NotSupportedError,
+            ExceptionMessages::indexOutsideRange(
+                "hardware sample rate",
+                audioContext->sampleRate(),
+                AudioUtilities::minAudioBufferSampleRate(),
+                ExceptionMessages::InclusiveBound,
+                AudioUtilities::maxAudioBufferSampleRate(),
+                ExceptionMessages::InclusiveBound));
+        return audioContext;
+    }
     // This starts the audio thread. The destination node's
     // provideInput() method will now be called repeatedly to render
     // audio.  Each time provideInput() is called, a portion of the
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index 47b96ec..189d728e 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -165,7 +165,7 @@
 SlimmingPaintV2
 SlimmingPaintOffsetCaching implied_by=SlimmingPaintV2
 SlimmingPaintStrictCullRectClipping
-SlimmingPaintSynchronizedPainting implied_by=SlimmingPaintV2
+SlimmingPaintSynchronizedPainting implied_by=SlimmingPaintV2, status=stable
 SlimmingPaintUnderInvalidationChecking
 StackedCSSPropertyAnimations status=experimental
 StyleSharing status=stable
diff --git a/third_party/WebKit/Source/platform/fonts/ScriptRunIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/ScriptRunIteratorTest.cpp
index 9cb7b56f..5ad70e32 100644
--- a/third_party/WebKit/Source/platform/fonts/ScriptRunIteratorTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/ScriptRunIteratorTest.cpp
@@ -238,76 +238,6 @@
         return result;
     }
 
-    static std::string MockCharString(UChar mockch)
-    {
-        ASSERT(mockch >= kMockCharMin && mockch < kMockCharLimit);
-        int code = mockch - kMockCharMin;
-
-        // We use set notation in these cases:
-        // - more than one of special, kLatin, kHan, kGreek
-        // - bracket and not common (since non-set brackets are common)
-        bool isBracket = (code & kCodeBracketBit) != 0;
-        bool isSpecial = (mockch & kCodeSpecialMask) != 0;
-        bool isCommon = (mockch & kCodeSpecialMask) == kCodeSpecialCommon;
-        char c;
-        if (isBracket) {
-            if (code & kCodeSquareBracketBit) {
-                if (code & kCodeBracketCloseBit) {
-                    c = ']';
-                } else {
-                    c = '[';
-                }
-            } else {
-                if (code & kCodeBracketCloseBit) {
-                    c = ')';
-                } else {
-                    c = '(';
-                }
-            }
-        } else if (isSpecial) {
-            c = isCommon ? 'c' : 'i';
-        }
-        std::string result;
-        int listBits = kTable[code & kCodeListIndexMask];
-        while (listBits) {
-            switch (listBits & kListMask) {
-            case 0:
-                break;
-            case kLatin:
-                result += 'l';
-                break;
-            case kHan:
-                result += 'h';
-                break;
-            case kGreek:
-                result += 'g';
-                break;
-            }
-            listBits >>= kListShift;
-        }
-        bool needSet = result.length() + (isSpecial ? 1 : 0) > 1 || (isBracket && (result.length() > 0 || !isCommon));
-        if (needSet) {
-            std::string setResult("<");
-            if (isBracket) {
-                setResult += c;
-            }
-            if (isSpecial) {
-                if (isCommon) {
-                    setResult += "c";
-                } else {
-                    setResult += "i";
-                }
-            }
-            setResult += result;
-            setResult += ">";
-            return setResult;
-        }
-        if (isBracket || isSpecial) {
-            result = c;
-        }
-        return result;
-    }
-
     // We determine properties based on the offset from kMockCharMin:
     // bits 0-3 represent the list of l, h, c scripts (index into table)
     // bit 4-5 means: 0 plain, 1 common, 2 inherited, 3 illegal
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
index 2141d7d..c118ab60 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -33,9 +33,7 @@
 #include "platform/fonts/shaping/HarfBuzzShaper.h"
 
 #include "hb.h"
-#include "platform/LayoutUnit.h"
 #include "platform/Logging.h"
-#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/fonts/Character.h"
 #include "platform/fonts/Font.h"
 #include "platform/fonts/FontFallbackIterator.h"
@@ -49,9 +47,6 @@
 #include "wtf/text/Unicode.h"
 
 #include <algorithm>
-#include <list>
-#include <map>
-#include <string>
 #include <unicode/normlzr.h>
 #include <unicode/uchar.h>
 #include <unicode/uscript.h>
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.cpp
index dda1ebe..fa72aa8c 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.cpp
@@ -155,15 +155,6 @@
     }
 }
 
-static String subsequenceTypeAsDebugString(DisplayItem::Type type)
-{
-    switch (type) {
-        DEBUG_STRING_CASE(SubsequenceNegativeZOrder);
-        DEBUG_STRING_CASE(SubsequenceNormalFlowAndPositiveZOrder);
-        DEFAULT_CASE;
-    }
-}
-
 WTF::String DisplayItem::typeAsDebugString(Type type)
 {
     if (isDrawingType(type))
@@ -191,13 +182,6 @@
     if (isEndTransform3DType(type))
         return "End" + transform3DTypeAsDebugString(endTransform3DTypeToTransform3DType(type));
 
-    if (isSubsequenceType(type))
-        return subsequenceTypeAsDebugString(type);
-    if (isEndSubsequenceType(type))
-        return "End" + subsequenceTypeAsDebugString(endSubsequenceTypeToSubsequenceType(type));
-    if (isCachedSubsequenceType(type))
-        return "Cached" + subsequenceTypeAsDebugString(cachedSubsequenceTypeToSubsequenceType(type));
-
     switch (type) {
         DEBUG_STRING_CASE(BeginFilter);
         DEBUG_STRING_CASE(EndFilter);
@@ -211,6 +195,9 @@
         DEBUG_STRING_CASE(EndFixedPosition);
         DEBUG_STRING_CASE(BeginFixedPositionContainer);
         DEBUG_STRING_CASE(EndFixedPositionContainer);
+        DEBUG_STRING_CASE(Subsequence);
+        DEBUG_STRING_CASE(EndSubsequence);
+        DEBUG_STRING_CASE(CachedSubsequence);
         DEBUG_STRING_CASE(CachedDisplayItemList);
         DEBUG_STRING_CASE(UninitializedType);
         DEFAULT_CASE;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
index 35e1c4141..2670d44 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
@@ -168,14 +168,9 @@
         BeginFixedPositionContainer,
         EndFixedPositionContainer,
 
-        SubsequenceFirst,
-        SubsequenceNegativeZOrder = SubsequenceFirst,
-        SubsequenceNormalFlowAndPositiveZOrder,
-        SubsequenceLast = SubsequenceNormalFlowAndPositiveZOrder,
-        EndSubsequenceFirst,
-        EndSubsequenceLast = EndSubsequenceFirst + SubsequenceLast - SubsequenceFirst,
-        CachedSubsequenceFirst,
-        CachedSubsequenceLast = CachedSubsequenceFirst + SubsequenceLast - SubsequenceFirst,
+        Subsequence,
+        EndSubsequence,
+        CachedSubsequence,
 
         CachedDisplayItemList,
 
@@ -238,8 +233,8 @@
     {
         if (isCachedDrawingType(type))
             return cachedDrawingTypeToDrawingType(type);
-        if (isCachedSubsequenceType(type))
-            return cachedSubsequenceTypeToSubsequenceType(type);
+        if (type == CachedSubsequence)
+            return Subsequence;
         return type;
     }
 
@@ -319,13 +314,9 @@
 
     DEFINE_PAIRED_CATEGORY_METHODS(Transform3D, transform3D)
 
-    DEFINE_PAIRED_CATEGORY_METHODS(Subsequence, subsequence)
-    DEFINE_CATEGORY_METHODS(CachedSubsequence)
-    DEFINE_CONVERSION_METHODS(Subsequence, subsequence, CachedSubsequence, cachedSubsequence)
-
-    static bool isCachedType(Type type) { return isCachedDrawingType(type) || isCachedSubsequenceType(type) || type == CachedDisplayItemList; }
+    static bool isCachedType(Type type) { return isCachedDrawingType(type) || type == CachedSubsequence || type == CachedDisplayItemList; }
     bool isCached() const { return isCachedType(m_type); }
-    static bool isCacheableType(Type type) { return isDrawingType(type) || isSubsequenceType(type); }
+    static bool isCacheableType(Type type) { return isDrawingType(type) || type == Subsequence; }
     bool isCacheable() const { return !skippedCache() && isCacheableType(m_type); }
 
     virtual bool isBegin() const { return false; }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index 51bbe10..cbaa5e1 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -66,7 +66,7 @@
     // Verify noop begin/end pairs have been removed.
     if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) {
         const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList.size() - 2];
-        if (beginDisplayItem.isBegin() && !beginDisplayItem.isSubsequence() && !beginDisplayItem.drawsContent())
+        if (beginDisplayItem.isBegin() && beginDisplayItem.type() != DisplayItem::Subsequence && !beginDisplayItem.drawsContent())
             ASSERT(!displayItem.isEndAndPairedWith(beginDisplayItem.type()));
     }
 #endif
@@ -246,9 +246,9 @@
 
 void PaintController::copyCachedSubsequence(DisplayItemList::iterator& currentIt, DisplayItemList& updatedList)
 {
-    ASSERT(currentIt->isSubsequence());
+    ASSERT(currentIt->type() == DisplayItem::Subsequence);
     ASSERT(!currentIt->scope());
-    DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::subsequenceTypeToEndSubsequenceType(currentIt->type()), 0);
+    DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::EndSubsequence, 0);
     do {
         // We should always find the EndSubsequence display item.
         ASSERT(currentIt != m_currentPaintArtifact.displayItemList().end());
@@ -362,9 +362,9 @@
                 updatedList.appendByMoving(*currentIt);
                 ++currentIt;
             } else {
-                ASSERT(newDisplayItem.isCachedSubsequence());
+                ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence);
                 copyCachedSubsequence(currentIt, updatedList);
-                ASSERT(updatedList.last().isEndSubsequence());
+                ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence);
             }
         } else {
             ASSERT(!newDisplayItem.isDrawing()
@@ -458,7 +458,7 @@
         return;
     }
 
-    ASSERT(newIt->isSubsequence());
+    ASSERT(newIt->type() == DisplayItem::Subsequence);
 
 #ifndef NDEBUG
     CString messagePrefix = String::format("(In CachedSubsequence of %s)", newIt->clientDebugString().utf8().data()).utf8();
@@ -466,7 +466,7 @@
     CString messagePrefix = "(In CachedSubsequence)";
 #endif
 
-    DisplayItem::Id endSubsequenceId(newIt->client(), DisplayItem::subsequenceTypeToEndSubsequenceType(newIt->type()), 0);
+    DisplayItem::Id endSubsequenceId(newIt->client(), DisplayItem::EndSubsequence, 0);
     while (true) {
         ASSERT(newIt != m_newDisplayItemList.end());
         if (newIt->isCached())
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
index 84e2943..ec904277 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -42,9 +42,6 @@
 const DisplayItem::Type foregroundDrawingType = static_cast<DisplayItem::Type>(DisplayItem::DrawingPaintPhaseFirst + 4);
 const DisplayItem::Type backgroundDrawingType = DisplayItem::DrawingPaintPhaseFirst;
 const DisplayItem::Type clipType = DisplayItem::ClipFirst;
-const DisplayItem::Type subsequenceType = DisplayItem::SubsequenceNormalFlowAndPositiveZOrder;
-const DisplayItem::Type endSubsequenceType = DisplayItem::subsequenceTypeToEndSubsequenceType(subsequenceType);
-const DisplayItem::Type cachedSubsequenceType = DisplayItem::subsequenceTypeToCachedSubsequenceType(subsequenceType);
 
 class TestDisplayItemClient {
 public:
@@ -463,14 +460,14 @@
     GraphicsContext context(paintController());
 
     {
-        SubsequenceRecorder r(context, container1, subsequenceType);
+        SubsequenceRecorder r(context, container1);
         drawRect(context, container1, backgroundDrawingType, FloatRect(100, 100, 100, 100));
         drawRect(context, content1, backgroundDrawingType, FloatRect(100, 100, 50, 200));
         drawRect(context, content1, foregroundDrawingType, FloatRect(100, 100, 50, 200));
         drawRect(context, container1, foregroundDrawingType, FloatRect(100, 100, 100, 100));
     }
     {
-        SubsequenceRecorder r(context, container2, subsequenceType);
+        SubsequenceRecorder r(context, container2);
         drawRect(context, container2, backgroundDrawingType, FloatRect(100, 200, 100, 100));
         drawRect(context, content2, backgroundDrawingType, FloatRect(100, 200, 50, 200));
         drawRect(context, content2, foregroundDrawingType, FloatRect(100, 200, 50, 200));
@@ -479,44 +476,44 @@
     paintController().commitNewDisplayItems();
 
     EXPECT_DISPLAY_LIST(paintController().displayItemList(), 12,
-        TestDisplayItem(container1, subsequenceType),
+        TestDisplayItem(container1, DisplayItem::Subsequence),
         TestDisplayItem(container1, backgroundDrawingType),
         TestDisplayItem(content1, backgroundDrawingType),
         TestDisplayItem(content1, foregroundDrawingType),
         TestDisplayItem(container1, foregroundDrawingType),
-        TestDisplayItem(container1, endSubsequenceType),
+        TestDisplayItem(container1, DisplayItem::EndSubsequence),
 
-        TestDisplayItem(container2, subsequenceType),
+        TestDisplayItem(container2, DisplayItem::Subsequence),
         TestDisplayItem(container2, backgroundDrawingType),
         TestDisplayItem(content2, backgroundDrawingType),
         TestDisplayItem(content2, foregroundDrawingType),
         TestDisplayItem(container2, foregroundDrawingType),
-        TestDisplayItem(container2, endSubsequenceType));
+        TestDisplayItem(container2, DisplayItem::EndSubsequence));
 
     // Simulate the situation when container1 e.g. gets a z-index that is now greater than container2.
-    EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container2, subsequenceType));
-    EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container1, subsequenceType));
+    EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container2));
+    EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container1));
 
     EXPECT_DISPLAY_LIST(paintController().newDisplayItemList(), 2,
-        TestDisplayItem(container2, cachedSubsequenceType),
-        TestDisplayItem(container1, cachedSubsequenceType));
+        TestDisplayItem(container2, DisplayItem::CachedSubsequence),
+        TestDisplayItem(container1, DisplayItem::CachedSubsequence));
 
     paintController().commitNewDisplayItems();
 
     EXPECT_DISPLAY_LIST(paintController().displayItemList(), 12,
-        TestDisplayItem(container2, subsequenceType),
+        TestDisplayItem(container2, DisplayItem::Subsequence),
         TestDisplayItem(container2, backgroundDrawingType),
         TestDisplayItem(content2, backgroundDrawingType),
         TestDisplayItem(content2, foregroundDrawingType),
         TestDisplayItem(container2, foregroundDrawingType),
-        TestDisplayItem(container2, endSubsequenceType),
+        TestDisplayItem(container2, DisplayItem::EndSubsequence),
 
-        TestDisplayItem(container1, subsequenceType),
+        TestDisplayItem(container1, DisplayItem::Subsequence),
         TestDisplayItem(container1, backgroundDrawingType),
         TestDisplayItem(content1, backgroundDrawingType),
         TestDisplayItem(content1, foregroundDrawingType),
         TestDisplayItem(container1, foregroundDrawingType),
-        TestDisplayItem(container1, endSubsequenceType));
+        TestDisplayItem(container1, DisplayItem::EndSubsequence));
 }
 
 TEST_F(PaintControllerTest, OutOfOrderNoCrash)
@@ -555,41 +552,41 @@
     GraphicsContext context(paintController());
 
     {
-        SubsequenceRecorder r(context, container1, subsequenceType);
+        SubsequenceRecorder r(context, container1);
         drawRect(context, container1, backgroundDrawingType, FloatRect(100, 100, 100, 100));
         {
-            SubsequenceRecorder r(context, content1, subsequenceType);
+            SubsequenceRecorder r(context, content1);
             drawRect(context, content1, backgroundDrawingType, FloatRect(100, 100, 50, 200));
             drawRect(context, content1, foregroundDrawingType, FloatRect(100, 100, 50, 200));
         }
         drawRect(context, container1, foregroundDrawingType, FloatRect(100, 100, 100, 100));
     }
     {
-        SubsequenceRecorder r(context, container2, subsequenceType);
+        SubsequenceRecorder r(context, container2);
         drawRect(context, container2, backgroundDrawingType, FloatRect(100, 200, 100, 100));
         {
-            SubsequenceRecorder r(context, content2, subsequenceType);
+            SubsequenceRecorder r(context, content2);
             drawRect(context, content2, backgroundDrawingType, FloatRect(100, 200, 50, 200));
         }
     }
     paintController().commitNewDisplayItems();
 
     EXPECT_DISPLAY_LIST(paintController().displayItemList(), 14,
-        TestDisplayItem(container1, subsequenceType),
+        TestDisplayItem(container1, DisplayItem::Subsequence),
         TestDisplayItem(container1, backgroundDrawingType),
-        TestDisplayItem(content1, subsequenceType),
+        TestDisplayItem(content1, DisplayItem::Subsequence),
         TestDisplayItem(content1, backgroundDrawingType),
         TestDisplayItem(content1, foregroundDrawingType),
-        TestDisplayItem(content1, endSubsequenceType),
+        TestDisplayItem(content1, DisplayItem::EndSubsequence),
         TestDisplayItem(container1, foregroundDrawingType),
-        TestDisplayItem(container1, endSubsequenceType),
+        TestDisplayItem(container1, DisplayItem::EndSubsequence),
 
-        TestDisplayItem(container2, subsequenceType),
+        TestDisplayItem(container2, DisplayItem::Subsequence),
         TestDisplayItem(container2, backgroundDrawingType),
-        TestDisplayItem(content2, subsequenceType),
+        TestDisplayItem(content2, DisplayItem::Subsequence),
         TestDisplayItem(content2, backgroundDrawingType),
-        TestDisplayItem(content2, endSubsequenceType),
-        TestDisplayItem(container2, endSubsequenceType));
+        TestDisplayItem(content2, DisplayItem::EndSubsequence),
+        TestDisplayItem(container2, DisplayItem::EndSubsequence));
 
     // Invalidate container1 but not content1.
     paintController().invalidate(container1, PaintInvalidationFull, nullptr);
@@ -599,44 +596,44 @@
 
     paintController().invalidate(container2, PaintInvalidationFull, nullptr);
     paintController().invalidate(content2, PaintInvalidationFull, nullptr);
-    EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container2, subsequenceType));
-    EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, content2, subsequenceType));
+    EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container2));
+    EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, content2));
     // Content2 now outputs foreground only.
     {
-        SubsequenceRecorder r(context, content2, subsequenceType);
+        SubsequenceRecorder r(context, content2);
         drawRect(context, content2, foregroundDrawingType, FloatRect(100, 200, 50, 200));
     }
     // Repaint container1 with foreground only.
     {
-        EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container1, subsequenceType));
-        SubsequenceRecorder r(context, container1, subsequenceType);
+        EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container1));
+        SubsequenceRecorder r(context, container1);
         // Use cached subsequence of content1.
-        EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, content1, subsequenceType));
+        EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, content1));
         drawRect(context, container1, foregroundDrawingType, FloatRect(100, 100, 100, 100));
     }
     EXPECT_DISPLAY_LIST(paintController().newDisplayItemList(), 7,
-        TestDisplayItem(content2, subsequenceType),
+        TestDisplayItem(content2, DisplayItem::Subsequence),
         TestDisplayItem(content2, foregroundDrawingType),
-        TestDisplayItem(content2, endSubsequenceType),
-        TestDisplayItem(container1, subsequenceType),
-        TestDisplayItem(content1, cachedSubsequenceType),
+        TestDisplayItem(content2, DisplayItem::EndSubsequence),
+        TestDisplayItem(container1, DisplayItem::Subsequence),
+        TestDisplayItem(content1, DisplayItem::CachedSubsequence),
         TestDisplayItem(container1, foregroundDrawingType),
-        TestDisplayItem(container1, endSubsequenceType));
+        TestDisplayItem(container1, DisplayItem::EndSubsequence));
 
     paintController().commitNewDisplayItems();
 
     EXPECT_DISPLAY_LIST(paintController().displayItemList(), 10,
-        TestDisplayItem(content2, subsequenceType),
+        TestDisplayItem(content2, DisplayItem::Subsequence),
         TestDisplayItem(content2, foregroundDrawingType),
-        TestDisplayItem(content2, endSubsequenceType),
+        TestDisplayItem(content2, DisplayItem::EndSubsequence),
 
-        TestDisplayItem(container1, subsequenceType),
-        TestDisplayItem(content1, subsequenceType),
+        TestDisplayItem(container1, DisplayItem::Subsequence),
+        TestDisplayItem(content1, DisplayItem::Subsequence),
         TestDisplayItem(content1, backgroundDrawingType),
         TestDisplayItem(content1, foregroundDrawingType),
-        TestDisplayItem(content1, endSubsequenceType),
+        TestDisplayItem(content1, DisplayItem::EndSubsequence),
         TestDisplayItem(container1, foregroundDrawingType),
-        TestDisplayItem(container1, endSubsequenceType));
+        TestDisplayItem(container1, DisplayItem::EndSubsequence));
 }
 
 TEST_F(PaintControllerTest, Scope)
diff --git a/third_party/WebKit/Source/platform/graphics/paint/README.md b/third_party/WebKit/Source/platform/graphics/paint/README.md
index 24918af0..f637743f 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/README.md
+++ b/third_party/WebKit/Source/platform/graphics/paint/README.md
@@ -55,7 +55,7 @@
   which the above should be interpreted
 
 The parent node pointers link the transform nodes in a hierarchy (the *transform
-tree*), which define how the transform for any painted content can be
+tree*), which defines how the transform for any painted content can be
 determined.
 
 ***promo
@@ -70,6 +70,32 @@
 TODO(jbroman): Explain flattening, etc., once it exists in the paint properties.
 ***
 
+### Effects
+
+Each paint chunk is associated with an [effect node](EffectPaintPropertyNode.h),
+which defines the effect (opacity, transfer mode, filter, mask, etc.) that
+should be applied to the content before or as it is composited into the content
+below.
+
+Each effect node has:
+
+* a floating-point opacity (from 0 to 1, inclusive)
+* a pointer to the parent node, which will be applied to the result of this
+  effect before or as it is composited into its parent in the effect tree
+
+The paret node pointers link the effect nodes in a hierarchy (the *effect
+tree*), which defines the dependencies between rasterization of different
+contents.
+
+One can imagine each effect node as corresponding roughly to a bitmap that is
+drawn before being composited into another bitmap, though for implementation
+reasons this may not be how it is actually implemented.
+
+*** aside
+TODO(jbroman): Explain the connection with the transform and clip trees, once it
+exists, as well as effects other than opacity.
+***
+
 ## Display items
 
 A display item is the smallest unit of a display list in Blink. Each display
diff --git a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceDisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceDisplayItem.h
index dc7f451..140ff4d0 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceDisplayItem.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceDisplayItem.h
@@ -13,25 +13,21 @@
 
 class BeginSubsequenceDisplayItem final : public PairedBeginDisplayItem {
 public:
-    BeginSubsequenceDisplayItem(const DisplayItemClientWrapper& client, DisplayItem::Type type)
-        : PairedBeginDisplayItem(client, type, sizeof(*this))
-    {
-        ASSERT(DisplayItem::isSubsequenceType(type));
-    }
+    BeginSubsequenceDisplayItem(const DisplayItemClientWrapper& client)
+        : PairedBeginDisplayItem(client, Subsequence, sizeof(*this))
+    { }
 };
 
 class EndSubsequenceDisplayItem final : public PairedEndDisplayItem {
 public:
-    EndSubsequenceDisplayItem(const DisplayItemClientWrapper& client, DisplayItem::Type type)
-        : PairedEndDisplayItem(client, type, sizeof(*this))
-    {
-        ASSERT(DisplayItem::isEndSubsequenceType(type));
-    }
+    EndSubsequenceDisplayItem(const DisplayItemClientWrapper& client)
+        : PairedEndDisplayItem(client, EndSubsequence, sizeof(*this))
+    { }
 
 #if ENABLE(ASSERT)
     bool isEndAndPairedWith(DisplayItem::Type otherType) const final
     {
-        return otherType == DisplayItem::endSubsequenceTypeToSubsequenceType(type());
+        return type() == EndSubsequence && otherType == Subsequence;
     }
 #endif
 };
diff --git a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
index 4531fe9..45067bc 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
@@ -13,7 +13,7 @@
 
 namespace blink {
 
-bool SubsequenceRecorder::useCachedSubsequenceIfPossible(GraphicsContext& context, const DisplayItemClientWrapper& client, DisplayItem::Type type)
+bool SubsequenceRecorder::useCachedSubsequenceIfPossible(GraphicsContext& context, const DisplayItemClientWrapper& client)
 {
     if (!RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled())
         return false;
@@ -24,7 +24,7 @@
     if (!context.paintController().clientCacheIsValid(client.displayItemClient()))
         return false;
 
-    context.paintController().createAndAppend<CachedDisplayItem>(client, DisplayItem::subsequenceTypeToCachedSubsequenceType(type));
+    context.paintController().createAndAppend<CachedDisplayItem>(client, DisplayItem::CachedSubsequence);
 
 #if ENABLE(ASSERT)
     // When under-invalidation checking is enabled, we output CachedSubsequence display item
@@ -36,11 +36,10 @@
     return true;
 }
 
-SubsequenceRecorder::SubsequenceRecorder(GraphicsContext& context, const DisplayItemClientWrapper& client, DisplayItem::Type type)
+SubsequenceRecorder::SubsequenceRecorder(GraphicsContext& context, const DisplayItemClientWrapper& client)
     : m_paintController(context.paintController())
     , m_client(client)
     , m_beginSubsequenceIndex(0)
-    , m_type(type)
 {
     if (!RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled())
         return;
@@ -49,7 +48,7 @@
         return;
 
     m_beginSubsequenceIndex = m_paintController.newDisplayItemList().size();
-    m_paintController.createAndAppend<BeginSubsequenceDisplayItem>(m_client, type);
+    m_paintController.createAndAppend<BeginSubsequenceDisplayItem>(m_client);
 }
 
 SubsequenceRecorder::~SubsequenceRecorder()
@@ -70,7 +69,7 @@
         }
     }
 
-    m_paintController.createAndAppend<EndSubsequenceDisplayItem>(m_client, DisplayItem::subsequenceTypeToEndSubsequenceType(m_type));
+    m_paintController.createAndAppend<EndSubsequenceDisplayItem>(m_client);
 }
 
 void SubsequenceRecorder::setUncacheable()
@@ -81,7 +80,7 @@
     if (m_paintController.displayItemConstructionIsDisabled())
         return;
 
-    ASSERT(m_paintController.newDisplayItemList()[m_beginSubsequenceIndex].isSubsequence());
+    ASSERT(m_paintController.newDisplayItemList()[m_beginSubsequenceIndex].type() == DisplayItem::Subsequence);
     m_paintController.newDisplayItemList()[m_beginSubsequenceIndex].setSkippedCache();
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.h b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.h
index 04127d1..498ec4ef 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.h
@@ -22,9 +22,9 @@
 //
 class PLATFORM_EXPORT SubsequenceRecorder {
 public:
-    static bool useCachedSubsequenceIfPossible(GraphicsContext&, const DisplayItemClientWrapper&, DisplayItem::Type);
+    static bool useCachedSubsequenceIfPossible(GraphicsContext&, const DisplayItemClientWrapper&);
 
-    SubsequenceRecorder(GraphicsContext&, const DisplayItemClientWrapper&, DisplayItem::Type);
+    SubsequenceRecorder(GraphicsContext&, const DisplayItemClientWrapper&);
     ~SubsequenceRecorder();
 
     void setUncacheable();
@@ -33,7 +33,6 @@
     PaintController& m_paintController;
     DisplayItemClientWrapper m_client;
     size_t m_beginSubsequenceIndex;
-    DisplayItem::Type m_type;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp
index 33fa5e26..66850722 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.cpp
+++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -467,7 +467,6 @@
         ThreadState::NoAllocationScope noAllocationScope(state);
 
         state->preGC();
-        StackFrameDepthScope stackDepthScope;
 
         // 1. Trace the thread local persistent roots. For thread local GCs we
         // don't trace the stack (ie. no conservative scanning) since this is
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
index 4ee87f0..10b30f8 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -329,7 +329,7 @@
 
 bool BaseHeap::lazySweepWithDeadline(double deadlineSeconds)
 {
-    // It might be heavy to call Platform::current()->monotonicallyIncreasingTime()
+    // It might be heavy to call Platform::current()->monotonicallyIncreasingTimeSeconds()
     // per page (i.e., 128 KB sweep or one LargeObject sweep), so we check
     // the deadline per 10 pages.
     static const int deadlineCheckInterval = 10;
@@ -342,7 +342,7 @@
     while (m_firstUnsweptPage) {
         sweepUnsweptPage();
         if (pageCount % deadlineCheckInterval == 0) {
-            if (deadlineSeconds <= Platform::current()->monotonicallyIncreasingTime()) {
+            if (deadlineSeconds <= Platform::current()->monotonicallyIncreasingTimeSeconds()) {
                 // Deadline has come.
                 Heap::reportMemoryUsageForTracing();
                 return !m_firstUnsweptPage;
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index 75bbf58..9ad69b6 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -751,7 +751,7 @@
     if (gcState() != IdleGCScheduled)
         return;
 
-    double idleDeltaInSeconds = deadlineSeconds - Platform::current()->monotonicallyIncreasingTime();
+    double idleDeltaInSeconds = deadlineSeconds - Platform::current()->monotonicallyIncreasingTimeSeconds();
     TRACE_EVENT2("blink_gc", "ThreadState::performIdleGC", "idleDeltaInSeconds", idleDeltaInSeconds, "estimatedMarkingTime", Heap::estimatedMarkingTime());
     if (idleDeltaInSeconds <= Heap::estimatedMarkingTime() && !Platform::current()->currentThread()->scheduler()->canExceedIdleDeadlineIfRequired()) {
         // If marking is estimated to take longer than the deadline and we can't
@@ -778,7 +778,7 @@
     if (sweepForbidden())
         return;
 
-    TRACE_EVENT1("blink_gc", "ThreadState::performIdleLazySweep", "idleDeltaInSeconds", deadlineSeconds - Platform::current()->monotonicallyIncreasingTime());
+    TRACE_EVENT1("blink_gc", "ThreadState::performIdleLazySweep", "idleDeltaInSeconds", deadlineSeconds - Platform::current()->monotonicallyIncreasingTimeSeconds());
 
     bool sweepCompleted = true;
     SweepForbiddenScope scope(this);
@@ -791,7 +791,7 @@
             // lazySweepWithDeadline() won't check the deadline until it sweeps
             // 10 pages. So we give a small slack for safety.
             double slack = 0.001;
-            double remainingBudget = deadlineSeconds - slack - Platform::current()->monotonicallyIncreasingTime();
+            double remainingBudget = deadlineSeconds - slack - Platform::current()->monotonicallyIncreasingTimeSeconds();
             if (remainingBudget <= 0 || !m_heaps[i]->lazySweepWithDeadline(deadlineSeconds)) {
                 // We couldn't finish the sweeping within the deadline.
                 // We request another idle task for the remaining sweeping.
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index 74ef7d51..10c3937 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -89,7 +89,7 @@
 
 struct decoder_source_mgr {
     struct jpeg_source_mgr pub; // "public" fields for IJG library
-    JPEGImageReader* decoder;
+    JPEGImageReader* reader;
 };
 
 enum jstate {
@@ -299,7 +299,7 @@
         , m_nextReadPosition(0)
         , m_lastSetByte(nullptr)
         , m_state(JPEG_HEADER)
-        , m_samples(0)
+        , m_samples(nullptr)
 #if USE(QCMSLIB)
         , m_transform(0)
 #endif
@@ -323,7 +323,7 @@
         m_src.pub.skip_input_data = skip_input_data;
         m_src.pub.resync_to_restart = jpeg_resync_to_restart;
         m_src.pub.term_source = term_source;
-        m_src.decoder = this;
+        m_src.reader = this;
 
 #if USE(ICCJPEG)
         // Retain ICC color profile markers for color management.
@@ -540,15 +540,10 @@
             m_info.colormap = 0;
 
             // Make a one-row-high sample array that will go away when done with
-            // image. Always make it big enough to hold an RGB row. Since this
+            // image. Always make it big enough to hold one RGBA row. Since this
             // uses the IJG memory manager, it must be allocated before the call
-            // to jpeg_start_compress().
-            // FIXME: note that some output color spaces do not need the samples
-            // buffer. Remove this allocation for those color spaces.
-            {
-                int samplesWidth = (m_info.out_color_space == JCS_YCbCr) ? computeYUVSize(&m_info, 0, ImageDecoder::SizeForMemoryAllocation).width() : m_info.output_width;
-                m_samples = (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, samplesWidth * 4, 1);
-            }
+            // to jpeg_start_decompress().
+            m_samples = allocateSampleArray();
 
             // Start decompressor.
             if (!jpeg_start_decompress(&m_info))
@@ -667,6 +662,23 @@
 #endif
 
 private:
+    JSAMPARRAY allocateSampleArray()
+    {
+        // Some output color spaces don't need the sample array: don't allocate in that case.
+#if defined(TURBO_JPEG_RGB_SWIZZLE)
+        if (turboSwizzled(m_info.out_color_space))
+            return nullptr;
+#endif
+        int width;
+
+        if (m_info.out_color_space == JCS_YCbCr)
+            width = computeYUVSize(&m_info, 0, ImageDecoder::SizeForMemoryAllocation).width();
+        else
+            width = m_info.output_width;
+
+        return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, width * 4, 1);
+    }
+
     void updateRestartPosition()
     {
         if (m_lastSetByte != m_info.src->next_input_byte) {
@@ -685,7 +697,8 @@
 
     RefPtr<SharedBuffer> m_data;
     JPEGImageDecoder* m_decoder;
-    // True if we need to back up to m_restartPosition.
+
+    // Input reading: True if we need to back up to m_restartPosition.
     bool m_needsRestart;
     // If libjpeg needed to restart, this is the position to restart from.
     unsigned m_restartPosition;
@@ -703,7 +716,6 @@
     jstate m_state;
 
     JSAMPARRAY m_samples;
-
     IntSize m_uvSize;
 
 #if USE(QCMSLIB)
@@ -711,12 +723,9 @@
 #endif
 };
 
-// Override the standard error method in the IJG JPEG decoder code.
-void error_exit(j_common_ptr cinfo)
+void error_exit(j_common_ptr cinfo) // Decoding failed: return control to the setjmp point.
 {
-    // Return control to the setjmp point.
-    decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_mgr*>(cinfo->err);
-    longjmp(err->setjmp_buffer, -1);
+    longjmp(reinterpret_cast_ptr<decoder_error_mgr*>(cinfo->err)->setjmp_buffer, -1);
 }
 
 void emit_message(j_common_ptr cinfo, int msg_level)
@@ -742,20 +751,17 @@
 
 void skip_input_data(j_decompress_ptr jd, long num_bytes)
 {
-    decoder_source_mgr* src = reinterpret_cast_ptr<decoder_source_mgr*>(jd->src);
-    src->decoder->skipBytes(num_bytes);
+    reinterpret_cast_ptr<decoder_source_mgr*>(jd->src)->reader->skipBytes(num_bytes);
 }
 
 boolean fill_input_buffer(j_decompress_ptr jd)
 {
-    decoder_source_mgr* src = reinterpret_cast_ptr<decoder_source_mgr*>(jd->src);
-    return src->decoder->fillBuffer();
+    return reinterpret_cast_ptr<decoder_source_mgr*>(jd->src)->reader->fillBuffer();
 }
 
 void term_source(j_decompress_ptr jd)
 {
-    decoder_source_mgr* src = reinterpret_cast_ptr<decoder_source_mgr*>(jd->src);
-    src->decoder->decoder()->complete();
+    reinterpret_cast_ptr<decoder_source_mgr*>(jd->src)->reader->decoder()->complete();
 }
 
 JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption colorOptions, size_t maxDecodedBytes)
diff --git a/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.cpp b/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.cpp
index b6d59cd..fc61113 100644
--- a/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.cpp
+++ b/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.cpp
@@ -58,6 +58,11 @@
     ASSERT(m_id.length());
 }
 
+void MediaStreamComponent::dispose()
+{
+    m_extraData.clear();
+}
+
 #if ENABLE(WEB_AUDIO)
 void MediaStreamComponent::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* provider)
 {
diff --git a/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.h b/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.h
index e8b7832a..8a826e21 100644
--- a/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.h
+++ b/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.h
@@ -46,6 +46,7 @@
 class WebAudioSourceProvider;
 
 class PLATFORM_EXPORT MediaStreamComponent final : public GarbageCollectedFinalized<MediaStreamComponent> {
+    USING_PRE_FINALIZER(MediaStreamComponent, dispose);
 public:
     class ExtraData {
     public:
@@ -55,6 +56,11 @@
     static MediaStreamComponent* create(MediaStreamSource*);
     static MediaStreamComponent* create(const String& id, MediaStreamSource*);
 
+    // |m_extraData| may hold pointers to GC objects indirectly, and it may touch
+    // eagerly finalized objects in destruction.
+    // So this class runs pre-finalizer to finalize |m_extraData| promptly.
+    void dispose();
+
     MediaStreamSource* source() const { return m_source.get(); }
 
     String id() const { return m_id; }
@@ -71,9 +77,6 @@
     ExtraData* extraData() const { return m_extraData.get(); }
     void setExtraData(PassOwnPtr<ExtraData> extraData) { m_extraData = extraData; }
 
-    // |m_extraData| may hold pointers GC objects, and it may touch them in destruction.
-    // So this class is eagerly finalized to finalize |m_extraData| promptly.
-    EAGERLY_FINALIZE();
     DECLARE_TRACE();
 
 private:
diff --git a/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp b/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
index 1854d20..9f017935 100644
--- a/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
+++ b/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
@@ -172,6 +172,8 @@
 // A lifetime test: delete LayerTreeView while running LinkHighlights.
 TEST(LinkHighlightImplTest, resetLayerTreeView)
 {
+    FrameTestHelpers::UseMockScrollbarSettings mockScrollbarSettings;
+
     OwnPtr<FakeCompositingWebViewClient> webViewClient = adoptPtr(new FakeCompositingWebViewClient());
 
     const std::string baseURL("http://www.test.com/");
diff --git a/third_party/WebKit/Source/web/WebDocument.cpp b/third_party/WebKit/Source/web/WebDocument.cpp
index e10b756..bd7f10d0 100644
--- a/third_party/WebKit/Source/web/WebDocument.cpp
+++ b/third_party/WebKit/Source/web/WebDocument.cpp
@@ -63,7 +63,6 @@
 #include "public/web/WebElement.h"
 #include "public/web/WebElementCollection.h"
 #include "public/web/WebFormElement.h"
-#include "public/web/WebNodeList.h"
 #include "web/WebLocalFrameImpl.h"
 #include "wtf/PassRefPtr.h"
 #include <v8.h>
diff --git a/third_party/WebKit/Source/web/WebKit.cpp b/third_party/WebKit/Source/web/WebKit.cpp
index b05429d..c892d8b0 100644
--- a/third_party/WebKit/Source/web/WebKit.cpp
+++ b/third_party/WebKit/Source/web/WebKit.cpp
@@ -134,12 +134,12 @@
 
 static double currentTimeFunction()
 {
-    return Platform::current()->currentTime();
+    return Platform::current()->currentTimeSeconds();
 }
 
 static double monotonicallyIncreasingTimeFunction()
 {
-    return Platform::current()->monotonicallyIncreasingTime();
+    return Platform::current()->monotonicallyIncreasingTimeSeconds();
 }
 
 static double systemTraceTimeFunction()
diff --git a/third_party/WebKit/Source/web/WebNode.cpp b/third_party/WebKit/Source/web/WebNode.cpp
index ba4cbbfa..7391012 100644
--- a/third_party/WebKit/Source/web/WebNode.cpp
+++ b/third_party/WebKit/Source/web/WebNode.cpp
@@ -55,7 +55,6 @@
 #include "public/web/WebDocument.h"
 #include "public/web/WebElement.h"
 #include "public/web/WebElementCollection.h"
-#include "public/web/WebNodeList.h"
 #include "public/web/WebPluginContainer.h"
 #include "web/FrameLoaderClientImpl.h"
 #include "web/WebLocalFrameImpl.h"
@@ -171,11 +170,6 @@
     return m_private->hasChildren();
 }
 
-WebNodeList WebNode::childNodes()
-{
-    return WebNodeList(m_private->childNodes());
-}
-
 bool WebNode::isLink() const
 {
     return m_private->isLink();
diff --git a/third_party/WebKit/Source/web/WebNodeList.cpp b/third_party/WebKit/Source/web/WebNodeList.cpp
deleted file mode 100644
index 8604056..0000000
--- a/third_party/WebKit/Source/web/WebNodeList.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "public/web/WebNodeList.h"
-
-#include "core/dom/Node.h"
-#include "core/dom/NodeList.h"
-#include "public/web/WebNode.h"
-#include "wtf/PassRefPtr.h"
-
-namespace blink {
-
-void WebNodeList::reset()
-{
-    m_private.reset();
-}
-
-void WebNodeList::assign(const WebNodeList& other)
-{
-    m_private = other.m_private;
-}
-
-WebNodeList::WebNodeList(const PassRefPtrWillBeRawPtr<NodeList>& list)
-    : m_private(list)
-{
-}
-
-WebNodeList& WebNodeList::operator=(const PassRefPtrWillBeRawPtr<NodeList>& list)
-{
-    m_private = list;
-    return *this;
-}
-
-unsigned WebNodeList::length() const
-{
-    return m_private->length();
-}
-
-WebNode WebNodeList::item(size_t index) const
-{
-    return WebNode(m_private->item(index));
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index 7be53ac..5c9b8a4 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -55,6 +55,7 @@
 #include "core/layout/HitTestResult.h"
 #include "core/layout/LayoutBox.h"
 #include "core/layout/LayoutPart.h"
+#include "core/layout/LayoutView.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/page/FocusController.h"
 #include "core/page/Page.h"
@@ -420,7 +421,6 @@
     IntRect windowRect, clipRect, unobscuredRect;
     Vector<IntRect> cutOutRects;
     calculateGeometry(windowRect, clipRect, unobscuredRect, cutOutRects);
-
     m_webPlugin->updateGeometry(windowRect, clipRect, unobscuredRect, cutOutRects, isVisible());
 }
 
@@ -944,33 +944,55 @@
     m_pendingInvalidationRect = IntRect();
 }
 
+void WebPluginContainerImpl::computeClipRectsForPlugin(
+    const HTMLFrameOwnerElement* ownerElement, IntRect& windowRect, IntRect& clippedLocalRect, IntRect& unclippedIntLocalRect) const
+{
+    ASSERT(ownerElement);
+
+    if (!ownerElement->layoutObject()) {
+        clippedLocalRect = IntRect();
+        unclippedIntLocalRect = IntRect();
+        return;
+    }
+
+    LayoutView* rootView = m_element->document().view()->layoutView();
+    while (rootView->frame()->ownerLayoutObject())
+        rootView = rootView->frame()->ownerLayoutObject()->view();
+
+    LayoutBox* box = toLayoutBox(ownerElement->layoutObject());
+
+    // Plugin frameRects are in absolute screen space.
+    IntRect frameRectInOwnerElementSpace = box->absoluteToLocalQuad(FloatRect(frameRect()), UseTransforms).enclosingBoundingBox();
+
+    LayoutRect unclippedAbsoluteRect(frameRectInOwnerElementSpace);
+    box->mapRectToPaintInvalidationBacking(rootView, unclippedAbsoluteRect, nullptr);
+
+    // The frameRect is already in absolute space.
+    windowRect = frameRect();
+
+    clippedLocalRect = enclosingIntRect(unclippedAbsoluteRect);
+    unclippedIntLocalRect = clippedLocalRect;
+    clippedLocalRect.intersect(rootView->frameView()->visibleContentRect());
+
+    // TODO(chrishtr): intentionally ignore transform, because the positioning of frameRect() does also. This is probably wrong.
+    unclippedIntLocalRect = box->absoluteToLocalQuad(FloatRect(unclippedIntLocalRect)).enclosingBoundingBox();
+    clippedLocalRect = box->absoluteToLocalQuad(FloatRect(clippedLocalRect)).enclosingBoundingBox();
+}
+
 void WebPluginContainerImpl::calculateGeometry(IntRect& windowRect, IntRect& clipRect, IntRect& unobscuredRect, Vector<IntRect>& cutOutRects)
 {
-    windowRect = toFrameView(parent())->contentsToRootFrame(frameRect());
-
-    // Calculate a clip-rect so that we don't overlap the scrollbars, etc.
-    clipRect = convertToContainingWindow(IntRect(0, 0, width(), height()));
-    unobscuredRect = clipRect;
-
     // document().layoutView() can be 0 when we receive messages from the
     // plugins while we are destroying a frame.
     // FIXME: Can we just check m_element->document().isActive() ?
     if (m_element->layoutObject()->document().layoutView()) {
         // Take our element and get the clip rect from the enclosing layer and
         // frame view.
-        IntRect elementUnobscuredRect;
-        IntRect elementWindowClipRect = m_element->document().view()->clipRectsForFrameOwner(m_element, &elementUnobscuredRect);
-        clipRect.intersect(elementWindowClipRect);
-        unobscuredRect.intersect(elementUnobscuredRect);
+        computeClipRectsForPlugin(m_element, windowRect, clipRect, unobscuredRect);
     }
-
-    clipRect.move(-windowRect.x(), -windowRect.y());
-    unobscuredRect.move(-windowRect.x(), -windowRect.y());
-
     getPluginOcclusions(m_element, this->parent(), frameRect(), cutOutRects);
     // Convert to the plugin position.
     for (size_t i = 0; i < cutOutRects.size(); i++)
         cutOutRects[i].move(-frameRect().x(), -frameRect().y());
 }
 
-} // namespace blink
+} // namespace blinkf
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
index 131eb18..eaff5bd 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
@@ -165,6 +165,12 @@
 #endif
 
 private:
+    // Sets |windowRect| to the content rect of the plugin in screen space.
+    // Sets |clippedAbsoluteRect| to the visible rect for the plugin, clipped to the visible screen of the root frame, in local space of the plugin.
+    // Sets |unclippedAbsoluteRect| to the visible rect for the plugin (but without also clipping to the screen), in local space of the plugin.
+    void computeClipRectsForPlugin(
+        const HTMLFrameOwnerElement* pluginOwnerElement, IntRect& windowRect, IntRect& clippedLocalRect, IntRect& unclippedIntLocalRect) const;
+
     WebPluginContainerImpl(HTMLPlugInElement*, WebPlugin*);
     ~WebPluginContainerImpl() override;
 
diff --git a/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp b/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp
index c3337da..8458c4c 100644
--- a/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp
+++ b/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp
@@ -30,6 +30,7 @@
 
 #include "config.h"
 
+#include "core/dom/NodeTraversal.h"
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebPrerender.h"
@@ -37,15 +38,12 @@
 #include "public/platform/WebString.h"
 #include "public/platform/WebUnitTestSupport.h"
 #include "public/web/WebCache.h"
-#include "public/web/WebDocument.h"
-#include "public/web/WebElement.h"
 #include "public/web/WebFrame.h"
-#include "public/web/WebNode.h"
-#include "public/web/WebNodeList.h"
 #include "public/web/WebPrerendererClient.h"
 #include "public/web/WebScriptSource.h"
 #include "public/web/WebView.h"
 #include "public/web/WebViewClient.h"
+#include "web/WebLocalFrameImpl.h"
 #include "web/tests/FrameTestHelpers.h"
 #include "wtf/OwnPtr.h"
 #include <functional>
@@ -199,31 +197,30 @@
         WebCache::clear();
     }
 
-    WebElement console()
+    Element& console()
     {
-        WebElement console = m_webViewHelper.webView()->mainFrame()->document().getElementById("console");
-        ASSERT(console.hasHTMLTagName("UL"));
-        return console;
+        Document* document = m_webViewHelper.webViewImpl()->mainFrameImpl()->frame()->document();
+        Element* console = document->getElementById("console");
+        ASSERT(isHTMLUListElement(console));
+        return *console;
     }
 
     unsigned consoleLength()
     {
-        return console().childNodes().length() - 1;
+        return console().countChildren() - 1;
     }
 
-    std::string consoleAt(unsigned i)
+    WebString consoleAt(unsigned i)
     {
         ASSERT(consoleLength() > i);
 
-        WebNode consoleListItem = console().childNodes().item(1 + i);
-        ASSERT(consoleListItem.isElementNode());
-        ASSERT(consoleListItem.to<WebElement>().hasHTMLTagName("LI"));
-        ASSERT(consoleListItem.hasChildNodes());
+        Node* item = NodeTraversal::childAt(console(), 1 + i);
 
-        WebNode textNode = consoleListItem.firstChild();
-        ASSERT(textNode.isTextNode());
+        ASSERT(item);
+        ASSERT(isHTMLLIElement(item));
+        ASSERT(item->hasChildren());
 
-        return textNode.nodeValue().utf8().data();
+        return item->textContent();
     }
 
     void executeScript(const char* code)
diff --git a/third_party/WebKit/Source/web/tests/TextFinderTest.cpp b/third_party/WebKit/Source/web/tests/TextFinderTest.cpp
index b286d54..0d657a3 100644
--- a/third_party/WebKit/Source/web/tests/TextFinderTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TextFinderTest.cpp
@@ -414,7 +414,7 @@
             // Check that the proxy wasn't installed yet.
             ASSERT_NE(Platform::current(), this);
             m_fallbackPlatform = Platform::current();
-            m_timeCounter = m_fallbackPlatform->currentTime();
+            m_timeCounter = m_fallbackPlatform->currentTimeSeconds();
             Platform::initialize(this);
             ASSERT_EQ(Platform::current(), this);
         }
@@ -436,7 +436,7 @@
         }
 
         // From blink::Platform:
-        double currentTime() override
+        double currentTimeSeconds() override
         {
             return ++m_timeCounter;
         }
@@ -453,9 +453,9 @@
         }
 
         // These two methods allow timers to work correctly.
-        double monotonicallyIncreasingTime() override
+        double monotonicallyIncreasingTimeSeconds() override
         {
-            return ensureFallback().monotonicallyIncreasingTime();
+            return ensureFallback().monotonicallyIncreasingTimeSeconds();
         }
 
         WebThread* currentThread() override { return ensureFallback().currentThread(); }
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
index f8edd53..f5b433e 100644
--- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
+++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
@@ -1119,64 +1119,6 @@
     webViewImpl()->mainFrameImpl()->setClient(oldClient);
 }
 
-// Tests that calling scroll into view on a visible element doesn cause
-// a scroll due to a fractional offset. Bug crbug.com/463356.
-TEST_P(ParameterizedVisualViewportTest, ScrollIntoViewFractionalOffset)
-{
-    initializeWithAndroidSettings();
-
-    webViewImpl()->resize(IntSize(1000, 1000));
-
-    registerMockedHttpURLLoad("scroll-into-view.html");
-    navigateTo(m_baseURL + "scroll-into-view.html");
-
-    FrameView& frameView = *webViewImpl()->mainFrameImpl()->frameView();
-    ScrollableArea* layoutViewportScrollableArea = frameView.layoutViewportScrollableArea();
-    VisualViewport& visualViewport = frame()->page()->frameHost().visualViewport();
-    Element* inputBox = frame()->document()->getElementById("box");
-
-    webViewImpl()->setPageScaleFactor(2);
-
-    // The element is already in the view so the scrollIntoView shouldn't move
-    // the viewport at all.
-    webViewImpl()->setVisualViewportOffset(WebFloatPoint(250.25f, 100.25f));
-    layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.75), ProgrammaticScroll);
-    inputBox->scrollIntoViewIfNeeded(false);
-
-    EXPECT_POINT_EQ(DoublePoint(0, 900.75), layoutViewportScrollableArea->scrollPositionDouble());
-    EXPECT_POINT_EQ(FloatPoint(250.25f, 100.25f), visualViewport.location());
-
-    // Change the fractional part of the frameview to one that would round down.
-    layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.125), ProgrammaticScroll);
-    inputBox->scrollIntoViewIfNeeded(false);
-
-    EXPECT_POINT_EQ(DoublePoint(0, 900.125), layoutViewportScrollableArea->scrollPositionDouble());
-    EXPECT_POINT_EQ(FloatPoint(250.25f, 100.25f), visualViewport.location());
-
-    // Repeat both tests above with the visual viewport at a high fractional.
-    webViewImpl()->setVisualViewportOffset(WebFloatPoint(250.875f, 100.875f));
-    layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.75), ProgrammaticScroll);
-    inputBox->scrollIntoViewIfNeeded(false);
-
-    EXPECT_POINT_EQ(DoublePoint(0, 900.75), layoutViewportScrollableArea->scrollPositionDouble());
-    EXPECT_POINT_EQ(FloatPoint(250.875f, 100.875f), visualViewport.location());
-
-    // Change the fractional part of the frameview to one that would round down.
-    layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.125), ProgrammaticScroll);
-    inputBox->scrollIntoViewIfNeeded(false);
-
-    EXPECT_POINT_EQ(DoublePoint(0, 900.125), layoutViewportScrollableArea->scrollPositionDouble());
-    EXPECT_POINT_EQ(FloatPoint(250.875f, 100.875f), visualViewport.location());
-
-    // Both viewports with a 0.5 fraction.
-    webViewImpl()->setVisualViewportOffset(WebFloatPoint(250.5f, 100.5f));
-    layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.5), ProgrammaticScroll);
-    inputBox->scrollIntoViewIfNeeded(false);
-
-    EXPECT_POINT_EQ(DoublePoint(0, 900.5), layoutViewportScrollableArea->scrollPositionDouble());
-    EXPECT_POINT_EQ(FloatPoint(250.5f, 100.5f), visualViewport.location());
-}
-
 // Top controls can make an unscrollable page temporarily scrollable, causing
 // a scroll clamp when the page is resized. Make sure this bug is fixed.
 // crbug.com/437620
@@ -1469,84 +1411,6 @@
     EXPECT_SIZE_EQ(bounds.size(), boundsInViewport.size());
 }
 
-// Test that the various window.scroll and document.body.scroll properties and
-// methods work unchanged from the pre-virtual viewport mode.
-TEST_P(ParameterizedVisualViewportTest, bodyAndWindowScrollPropertiesAccountForViewport)
-{
-    initializeWithAndroidSettings();
-
-    webViewImpl()->resize(IntSize(200, 300));
-
-    // Load page with no main frame scrolling.
-    registerMockedHttpURLLoad("200-by-300-viewport.html");
-    navigateTo(m_baseURL + "200-by-300-viewport.html");
-
-    VisualViewport& visualViewport = frame()->page()->frameHost().visualViewport();
-    visualViewport.setScale(2);
-
-    // Chrome's quirky behavior regarding viewport scrolling means we treat the
-    // body element as the viewport and don't apply scrolling to the HTML
-    // element.
-    RuntimeEnabledFeatures::setScrollTopLeftInteropEnabled(false);
-
-    LocalDOMWindow* window = webViewImpl()->mainFrameImpl()->frame()->localDOMWindow();
-    window->scrollTo(100, 150);
-    EXPECT_EQ(100, window->scrollX());
-    EXPECT_EQ(150, window->scrollY());
-    EXPECT_FLOAT_POINT_EQ(FloatPoint(100, 150), visualViewport.location());
-
-    HTMLElement* body = toHTMLBodyElement(window->document()->body());
-    body->setScrollLeft(50);
-    body->setScrollTop(130);
-    EXPECT_EQ(50, body->scrollLeft());
-    EXPECT_EQ(130, body->scrollTop());
-    EXPECT_FLOAT_POINT_EQ(FloatPoint(50, 130), visualViewport.location());
-
-    HTMLElement* documentElement = toHTMLElement(window->document()->documentElement());
-    documentElement->setScrollLeft(40);
-    documentElement->setScrollTop(50);
-    EXPECT_EQ(0, documentElement->scrollLeft());
-    EXPECT_EQ(0, documentElement->scrollTop());
-    EXPECT_FLOAT_POINT_EQ(FloatPoint(50, 130), visualViewport.location());
-
-    visualViewport.setLocation(FloatPoint(10, 20));
-    EXPECT_EQ(10, body->scrollLeft());
-    EXPECT_EQ(20, body->scrollTop());
-    EXPECT_EQ(0, documentElement->scrollLeft());
-    EXPECT_EQ(0, documentElement->scrollTop());
-    EXPECT_EQ(10, window->scrollX());
-    EXPECT_EQ(20, window->scrollY());
-
-    // Turning on the standards-compliant viewport scrolling impl should make
-    // the document element the viewport and not body.
-    RuntimeEnabledFeatures::setScrollTopLeftInteropEnabled(true);
-
-    window->scrollTo(100, 150);
-    EXPECT_EQ(100, window->scrollX());
-    EXPECT_EQ(150, window->scrollY());
-    EXPECT_FLOAT_POINT_EQ(FloatPoint(100, 150), visualViewport.location());
-
-    body->setScrollLeft(50);
-    body->setScrollTop(130);
-    EXPECT_EQ(0, body->scrollLeft());
-    EXPECT_EQ(0, body->scrollTop());
-    EXPECT_FLOAT_POINT_EQ(FloatPoint(100, 150), visualViewport.location());
-
-    documentElement->setScrollLeft(40);
-    documentElement->setScrollTop(50);
-    EXPECT_EQ(40, documentElement->scrollLeft());
-    EXPECT_EQ(50, documentElement->scrollTop());
-    EXPECT_FLOAT_POINT_EQ(FloatPoint(40, 50), visualViewport.location());
-
-    visualViewport.setLocation(FloatPoint(10, 20));
-    EXPECT_EQ(0, body->scrollLeft());
-    EXPECT_EQ(0, body->scrollTop());
-    EXPECT_EQ(10, documentElement->scrollLeft());
-    EXPECT_EQ(20, documentElement->scrollTop());
-    EXPECT_EQ(10, window->scrollX());
-    EXPECT_EQ(20, window->scrollY());
-}
-
 // Tests that when a new frame is created, it is created with the intended
 // size (i.e. viewport at minimum scale, 100x200 / 0.5).
 TEST_P(ParameterizedVisualViewportTest, TestMainFrameInitializationSizing)
diff --git a/third_party/WebKit/Source/web/web.gypi b/third_party/WebKit/Source/web/web.gypi
index bf5c99b..60ae1776 100644
--- a/third_party/WebKit/Source/web/web.gypi
+++ b/third_party/WebKit/Source/web/web.gypi
@@ -179,7 +179,6 @@
       'WebMediaStreamRegistry.cpp',
       'WebNetworkStateNotifier.cpp',
       'WebNode.cpp',
-      'WebNodeList.cpp',
       'WebOptionElement.cpp',
       'WebPageImportanceSignals.cpp',
       'WebPagePopupImpl.cpp',
diff --git a/third_party/WebKit/Source/wtf/PartitionAlloc.h b/third_party/WebKit/Source/wtf/PartitionAlloc.h
index 472d682..74b1881 100644
--- a/third_party/WebKit/Source/wtf/PartitionAlloc.h
+++ b/third_party/WebKit/Source/wtf/PartitionAlloc.h
@@ -743,6 +743,12 @@
     size_t requestedSize = size;
     size = partitionCookieSizeAdjustAdd(size);
     PartitionBucket* bucket = partitionGenericSizeToBucket(root, size);
+    // TODO(bashi): Remove following RELEAE_ASSERT()s once we find the cause of
+    // http://crbug.com/514141
+#if OS(ANDROID)
+    RELEASE_ASSERT(bucket >= &root->buckets[0] || bucket == &PartitionRootGeneric::gPagedBucket);
+    RELEASE_ASSERT(bucket <= &root->buckets[kGenericNumBuckets - 1] || bucket == &PartitionRootGeneric::gPagedBucket);
+#endif
     spinLockLock(&root->lock);
     void* ret = partitionBucketAlloc(root, flags, size, bucket);
     spinLockUnlock(&root->lock);
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
index 4c2f2bc..dd8a9e8 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -408,4 +408,14 @@
         printer.cleanup()
 
 if __name__ == '__main__':
-    sys.exit(main(sys.argv[1:], sys.stdout, sys.stderr))
+    exit_code = main(sys.argv[1:], sys.stdout, sys.stderr)
+    # Temporary logging to try and diagnose hangs on the Windows bots.
+    if 'win_chromium_rel_ng' in sys.argv:
+        print "Exiting with exit code: %d" % exit_code  # pylint: disable=E1601
+
+    try:
+        sys.exit(exit_code)
+    finally:
+        # Temporary logging to try and diagnose hangs on the Windows bots.
+        if 'win_chromium_rel_ng' in sys.argv:
+            print "sys.exit completed"  # pylint: disable=E1601
diff --git a/third_party/WebKit/public/blink_headers.gypi b/third_party/WebKit/public/blink_headers.gypi
index 2d2ebc2..45c5335 100644
--- a/third_party/WebKit/public/blink_headers.gypi
+++ b/third_party/WebKit/public/blink_headers.gypi
@@ -435,7 +435,6 @@
       "web/WebNavigatorContentUtilsClient.h",
       "web/WebNetworkStateNotifier.h",
       "web/WebNode.h",
-      "web/WebNodeList.h",
       "web/WebOptionElement.h",
       "web/WebPagePopup.h",
       "web/WebPageSerializer.h",
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index cdc1a5b..d1713f93 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -426,12 +426,12 @@
     virtual WebString defaultLocale() { return WebString(); }
 
     // Wall clock time in seconds since the epoch.
-    virtual double currentTime() { return 0; }
+    virtual double currentTimeSeconds() { return 0; }
 
     // Monotonically increasing time in seconds from an arbitrary fixed point in the past.
     // This function is expected to return at least millisecond-precision values. For this reason,
     // it is recommended that the fixed point be no further in the past than the epoch.
-    virtual double monotonicallyIncreasingTime() { return 0; }
+    virtual double monotonicallyIncreasingTimeSeconds() { return 0; }
 
     // System trace time in seconds. For example, on Chrome OS, this timestamp should be
     // synchronized with ftrace timestamps.
diff --git a/third_party/WebKit/public/web/WebNode.h b/third_party/WebKit/public/web/WebNode.h
index 1010489..5be9e354 100644
--- a/third_party/WebKit/public/web/WebNode.h
+++ b/third_party/WebKit/public/web/WebNode.h
@@ -45,7 +45,6 @@
 class WebDocument;
 class WebElement;
 class WebElementCollection;
-class WebNodeList;
 class WebPluginContainer;
 
 // Provides access to some properties of a DOM node.
@@ -83,7 +82,6 @@
     BLINK_EXPORT WebNode previousSibling() const;
     BLINK_EXPORT WebNode nextSibling() const;
     BLINK_EXPORT bool hasChildNodes() const;
-    BLINK_EXPORT WebNodeList childNodes();
     BLINK_EXPORT bool isLink() const;
     BLINK_EXPORT bool isDocumentNode() const;
     BLINK_EXPORT bool isCommentNode() const;
diff --git a/third_party/WebKit/public/web/WebNodeList.h b/third_party/WebKit/public/web/WebNodeList.h
deleted file mode 100644
index 4e7dcf9..0000000
--- a/third_party/WebKit/public/web/WebNodeList.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebNodeList_h
-#define WebNodeList_h
-
-#include "public/platform/WebCommon.h"
-#include "public/platform/WebPrivatePtr.h"
-
-#if BLINK_IMPLEMENTATION
-#include "platform/heap/Handle.h"
-namespace WTF { template <typename T> class PassRefPtr; }
-#endif
-
-namespace blink {
-
-class NodeList;
-class WebNode;
-
-// Provides readonly access to some properties of a DOM node.
-class WebNodeList {
-public:
-    ~WebNodeList() { reset(); }
-
-    WebNodeList() { }
-    WebNodeList(const WebNodeList& n) { assign(n); }
-    WebNodeList& operator=(const WebNodeList& n)
-    {
-        assign(n);
-        return *this;
-    }
-
-    BLINK_EXPORT void reset();
-    BLINK_EXPORT void assign(const WebNodeList&);
-
-    BLINK_EXPORT unsigned length() const;
-    BLINK_EXPORT WebNode item(size_t) const;
-
-#if BLINK_IMPLEMENTATION
-    WebNodeList(const PassRefPtrWillBeRawPtr<NodeList>&);
-    WebNodeList& operator=(const PassRefPtrWillBeRawPtr<NodeList>&);
-#endif
-
-private:
-    WebPrivatePtr<NodeList> m_private;
-};
-
-} // namespace blink
-
-#endif
diff --git a/third_party/mojo/mojo_edk_tests.gyp b/third_party/mojo/mojo_edk_tests.gyp
index 34f590847..aee91375 100644
--- a/third_party/mojo/mojo_edk_tests.gyp
+++ b/third_party/mojo/mojo_edk_tests.gyp
@@ -34,10 +34,11 @@
       'target_name': 'mojo_public_bindings_unittests',
       'type': 'executable',
       'dependencies': [
+        '../../mojo/mojo_base.gyp:mojo_environment_chromium',
+        '../../mojo/mojo_base.gyp:mojo_message_pump_lib',
         '../../testing/gtest.gyp:gtest',
         'mojo_edk.gyp:mojo_run_all_unittests',
         'mojo_public.gyp:mojo_cpp_bindings',
-        'mojo_public.gyp:mojo_environment_standalone',
         'mojo_public.gyp:mojo_public_bindings_test_utils',
         'mojo_public.gyp:mojo_public_test_interfaces',
         'mojo_public.gyp:mojo_public_test_utils',
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/BUILD.gn b/third_party/mojo/src/mojo/public/cpp/bindings/tests/BUILD.gn
index a0c18ba..4b55bb0 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/BUILD.gn
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -38,13 +38,14 @@
 
   deps = [
     ":mojo_public_bindings_test_utils",
+    "//mojo/environment:chromium",
+    "//mojo/message_pump",
     "//testing/gtest",
   ]
 
   mojo_sdk_deps = [
     "mojo/public/cpp/bindings",
     "mojo/public/cpp/bindings:callback",
-    "mojo/public/cpp/environment:standalone",
     "mojo/public/cpp/system",
     "mojo/public/cpp/test_support:test_utils",
     "mojo/public/cpp/utility",
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/array_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/array_unittest.cc
index 293dc95..8befe81 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/array_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/array_unittest.cc
@@ -7,7 +7,6 @@
 #include "mojo/public/cpp/bindings/lib/array_serialization.h"
 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
 #include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -20,13 +19,7 @@
 using mojo::internal::FixedBufferForTesting;
 using mojo::internal::String_Data;
 
-class ArrayTest : public testing::Test {
- public:
-  ~ArrayTest() override {}
-
- private:
-  Environment env_;
-};
+using ArrayTest = testing::Test;
 
 // Tests that basic Array operations work.
 TEST_F(ArrayTest, Basic) {
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc
index 242f9e2..83d74f9 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/binding_callback_unittest.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/message_loop/message_loop.h"
 #include "build/build_config.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_ptr.h"
 #include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "mojo/public/cpp/test_support/test_support.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -112,6 +112,7 @@
 
 class BindingCallbackTest : public testing::Test {
  public:
+  BindingCallbackTest() : loop_(common::MessagePumpMojo::Create()) {}
   ~BindingCallbackTest() override {}
 
  protected:
@@ -121,8 +122,7 @@
   void PumpMessages() { loop_.RunUntilIdle(); }
 
  private:
-  Environment env_;
-  RunLoop loop_;
+  base::MessageLoop loop_;
 };
 
 // Tests that the InterfacePtr and the Binding can communicate with each
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/binding_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/binding_unittest.cc
index ecba3ed..1462b33 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/binding_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/binding_unittest.cc
@@ -5,11 +5,11 @@
 // Note: This file tests both binding.h (mojo::Binding) and strong_binding.h
 // (mojo::StrongBinding).
 
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/macros.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -19,14 +19,13 @@
 
 class BindingTestBase : public testing::Test {
  public:
-  BindingTestBase() {}
+  BindingTestBase() : loop_(common::MessagePumpMojo::Create()) {}
   ~BindingTestBase() override {}
 
-  RunLoop& loop() { return loop_; }
+  base::MessageLoop& loop() { return loop_; }
 
  private:
-  Environment env_;
-  RunLoop loop_;
+  base::MessageLoop loop_;
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(BindingTestBase);
 };
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/connector_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/connector_unittest.cc
index c62794e7..febc72e 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/connector_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/connector_unittest.cc
@@ -5,12 +5,12 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/lib/connector.h"
 #include "mojo/public/cpp/bindings/lib/message_builder.h"
 #include "mojo/public/cpp/bindings/tests/message_queue.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/macros.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
@@ -73,7 +73,7 @@
 
 class ConnectorTest : public testing::Test {
  public:
-  ConnectorTest() {}
+  ConnectorTest() : loop_(common::MessagePumpMojo::Create()) {}
 
   void SetUp() override {
     CreateMessagePipe(nullptr, &handle0_, &handle1_);
@@ -96,8 +96,7 @@
   ScopedMessagePipeHandle handle1_;
 
  private:
-  Environment env_;
-  RunLoop loop_;
+  base::MessageLoop loop_;
 };
 
 TEST_F(ConnectorTest, Basic) {
@@ -249,7 +248,7 @@
   // Close the other end of the pipe.
   handle1_.reset();
 
-  // Not observed yet because we haven't spun the RunLoop yet.
+  // Not observed yet because we haven't spun the message loop yet.
   EXPECT_FALSE(connector0.encountered_error());
 
   // Write failures are not reported.
@@ -259,7 +258,7 @@
   // Still not observed.
   EXPECT_FALSE(connector0.encountered_error());
 
-  // Spin the RunLoop, and then we should start observing the closed pipe.
+  // Spin the message loop, and then we should start observing the closed pipe.
   PumpMessages();
 
   EXPECT_TRUE(connector0.encountered_error());
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/equals_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/equals_unittest.cc
index 72b02d4..5306f1f 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/equals_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/equals_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "mojo/public/cpp/bindings/lib/value_traits.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -21,14 +20,9 @@
   return r.Pass();
 }
 
-class EqualsTest : public testing::Test {
- public:
-  ~EqualsTest() override {}
+using EqualsTest = testing::Test;
 
- private:
-  Environment env_;
-};
-}
+}  // namespace
 
 TEST_F(EqualsTest, NullStruct) {
   RectPtr r1;
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
index f936361..8487d0a 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -137,13 +137,14 @@
 
 class HandlePassingTest : public testing::Test {
  public:
+  HandlePassingTest() : loop_(common::MessagePumpMojo::Create()) {}
+
   void TearDown() override { PumpMessages(); }
 
   void PumpMessages() { loop_.RunUntilIdle(); }
 
  private:
-  Environment env_;
-  RunLoop loop_;
+  base::MessageLoop loop_;
 };
 
 struct DoStuffCallback {
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
index 6c19285..508787a 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
-#include "mojo/public/cpp/environment/environment.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h"
 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
@@ -119,7 +119,7 @@
       // Add some more and wait for re-entrant call to Output!
       calculator_->Add(
           1.0, MakeRunnable(&SelfDestructingMathCalculatorUI::Output, this));
-      RunLoop::current()->RunUntilIdle();
+      base::MessageLoop::current()->RunUntilIdle();
     } else {
       delete this;
     }
@@ -184,13 +184,13 @@
 
 class InterfacePtrTest : public testing::Test {
  public:
+  InterfacePtrTest() : loop_(common::MessagePumpMojo::Create()) {}
   ~InterfacePtrTest() override { loop_.RunUntilIdle(); }
 
   void PumpMessages() { loop_.RunUntilIdle(); }
 
  private:
-  Environment env_;
-  RunLoop loop_;
+  base::MessageLoop loop_;
 };
 
 TEST_F(InterfacePtrTest, IsBound) {
@@ -470,8 +470,7 @@
 };
 
 TEST(StrongConnectorTest, Math) {
-  Environment env;
-  RunLoop loop;
+  base::MessageLoop loop(common::MessagePumpMojo::Create());
 
   bool error_received = false;
   bool destroyed = false;
@@ -539,8 +538,7 @@
 };
 
 TEST(WeakConnectorTest, Math) {
-  Environment env;
-  RunLoop loop;
+  base::MessageLoop loop(common::MessagePumpMojo::Create());
 
   bool error_received = false;
   bool destroyed = false;
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/map_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/map_unittest.cc
index 44100a4..5b049a87 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/map_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/map_unittest.cc
@@ -10,7 +10,6 @@
 #include "mojo/public/cpp/bindings/map.h"
 #include "mojo/public/cpp/bindings/string.h"
 #include "mojo/public/cpp/bindings/tests/container_test_util.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
@@ -36,13 +35,7 @@
 
 const size_t kStringIntDataSize = 4;
 
-class MapTest : public testing::Test {
- public:
-  ~MapTest() override {}
-
- private:
-  Environment env_;
-};
+using MapTest = testing::Test;
 
 // Tests that basic Map operations work.
 TEST_F(MapTest, InsertWorks) {
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/request_response_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/request_response_unittest.cc
index 8bfeb5d5..1e85d4a3 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/request_response_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/request_response_unittest.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/sample_import.mojom.h"
 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -85,13 +85,13 @@
 
 class RequestResponseTest : public testing::Test {
  public:
+  RequestResponseTest() : loop_(common::MessagePumpMojo::Create()) {}
   ~RequestResponseTest() override { loop_.RunUntilIdle(); }
 
   void PumpMessages() { loop_.RunUntilIdle(); }
 
  private:
-  Environment env_;
-  RunLoop loop_;
+  base::MessageLoop loop_;
 };
 
 TEST_F(RequestResponseTest, EchoString) {
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/router_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/router_unittest.cc
index e6dcb5d..c9c9f018 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/router_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/router_unittest.cc
@@ -5,12 +5,12 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/lib/message_builder.h"
 #include "mojo/public/cpp/bindings/lib/router.h"
 #include "mojo/public/cpp/bindings/tests/message_queue.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/macros.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
@@ -125,7 +125,7 @@
 
 class RouterTest : public testing::Test {
  public:
-  RouterTest() {}
+  RouterTest() : loop_(common::MessagePumpMojo::Create()) {}
 
   void SetUp() override {
     CreateMessagePipe(nullptr, &handle0_, &handle1_);
@@ -140,8 +140,7 @@
   ScopedMessagePipeHandle handle1_;
 
  private:
-  Environment env_;
-  RunLoop loop_;
+  base::MessageLoop loop_;
 };
 
 TEST_F(RouterTest, BasicRequestResponse) {
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/sample_service_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
index 5d1617f..58878a7 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
@@ -6,8 +6,6 @@
 #include <ostream>
 #include <string>
 
-#include "mojo/public/cpp/environment/environment.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -313,16 +311,7 @@
   }
 };
 
-class BindingsSampleTest : public testing::Test {
- public:
-  BindingsSampleTest() {}
-  ~BindingsSampleTest() override {}
-
- private:
-  mojo::Environment env_;
-
-  MOJO_DISALLOW_COPY_AND_ASSIGN(BindingsSampleTest);
-};
+using BindingsSampleTest = testing::Test;
 
 TEST_F(BindingsSampleTest, Basic) {
   SimpleMessageReceiver receiver;
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
index 43955cb..15da0516 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
@@ -11,7 +11,6 @@
 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
 #include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "mojo/public/interfaces/bindings/tests/serialization_test_structs.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -80,7 +79,6 @@
   }
 
   mojo::internal::SerializationWarningObserverForTesting warning_observer_;
-  Environment env_;
 };
 
 TEST_F(SerializationWarningTest, HandleInStruct) {
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/struct_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/struct_unittest.cc
index 71069d27..24173e5 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/struct_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/struct_unittest.cc
@@ -5,7 +5,6 @@
 #include <string.h>
 
 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -72,13 +71,7 @@
   return output.Pass();
 }
 
-class StructTest : public testing::Test {
- public:
-  ~StructTest() override {}
-
- private:
-  Environment env_;
-};
+using StructTest = testing::Test;
 
 }  // namespace
 
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc
index 776ac14..704110a5 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/type_conversion_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/union_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/union_unittest.cc
index e008b74..e6fddb7 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/union_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/union_unittest.cc
@@ -3,6 +3,9 @@
 // found in the LICENSE file.
 
 #include <vector>
+
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/array.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/lib/array_internal.h"
@@ -10,9 +13,7 @@
 #include "mojo/public/cpp/bindings/lib/bounds_checker.h"
 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
 #include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
 #include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -220,7 +221,6 @@
 }
 
 TEST(UnionTest, OutOfAlignmentValidation) {
-  Environment environment;
   size_t size = sizeof(internal::PodUnion_Data);
   // Get an aligned object and shift the alignment.
   mojo::internal::FixedBufferForTesting aligned_buf(size + 1);
@@ -236,7 +236,6 @@
 }
 
 TEST(UnionTest, OOBValidation) {
-  Environment environment;
   size_t size = sizeof(internal::PodUnion_Data) - 1;
   mojo::internal::FixedBufferForTesting buf(size);
   internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf);
@@ -249,7 +248,6 @@
 }
 
 TEST(UnionTest, UnknownTagValidation) {
-  Environment environment;
   size_t size = sizeof(internal::PodUnion_Data);
   mojo::internal::FixedBufferForTesting buf(size);
   internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf);
@@ -318,7 +316,6 @@
 }
 
 TEST(UnionTest, NullStringValidation) {
-  Environment environment;
   size_t size = sizeof(internal::ObjectUnion_Data);
   mojo::internal::FixedBufferForTesting buf(size);
   internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf);
@@ -333,7 +330,6 @@
 }
 
 TEST(UnionTest, StringPointerOverflowValidation) {
-  Environment environment;
   size_t size = sizeof(internal::ObjectUnion_Data);
   mojo::internal::FixedBufferForTesting buf(size);
   internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf);
@@ -348,7 +344,6 @@
 }
 
 TEST(UnionTest, StringValidateOOB) {
-  Environment environment;
   size_t size = 32;
   mojo::internal::FixedBufferForTesting buf(size);
   internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf);
@@ -383,7 +378,6 @@
 }
 
 TEST(UnionTest, PodUnionInArraySerialization) {
-  Environment environment;
   Array<PodUnionPtr> array(2);
   array[0] = PodUnion::New();
   array[1] = PodUnion::New();
@@ -410,7 +404,6 @@
 }
 
 TEST(UnionTest, PodUnionInArraySerializationWithNull) {
-  Environment environment;
   Array<PodUnionPtr> array(2);
   array[0] = PodUnion::New();
 
@@ -437,7 +430,6 @@
 // TODO(azani): Move back in struct_unittest.cc when possible.
 // Struct tests
 TEST(UnionTest, Clone_Union) {
-  Environment environment;
   SmallStructPtr small_struct(SmallStruct::New());
   small_struct->pod_union = PodUnion::New();
   small_struct->pod_union->set_f_int8(10);
@@ -448,7 +440,6 @@
 
 // Serialization test of a struct with a union of plain old data.
 TEST(UnionTest, Serialization_UnionOfPods) {
-  Environment environment;
   SmallStructPtr small_struct(SmallStruct::New());
   small_struct->pod_union = PodUnion::New();
   small_struct->pod_union->set_f_int32(10);
@@ -467,7 +458,6 @@
 
 // Serialization test of a struct with a union of structs.
 TEST(UnionTest, Serialization_UnionOfObjects) {
-  Environment environment;
   SmallObjStructPtr obj_struct(SmallObjStruct::New());
   obj_struct->obj_union = ObjectUnion::New();
   String hello("hello world");
@@ -491,7 +481,6 @@
 
 // Validation test of a struct with a union.
 TEST(UnionTest, Validation_UnionsInStruct) {
-  Environment environment;
   SmallStructPtr small_struct(SmallStruct::New());
   small_struct->pod_union = PodUnion::New();
   small_struct->pod_union->set_f_int32(10);
@@ -515,7 +504,6 @@
 
 // Validation test of a struct union fails due to unknown union tag.
 TEST(UnionTest, Validation_PodUnionInStruct_Failure) {
-  Environment environment;
   SmallStructPtr small_struct(SmallStruct::New());
   small_struct->pod_union = PodUnion::New();
   small_struct->pod_union->set_f_int32(10);
@@ -540,7 +528,6 @@
 
 // Validation fails due to non-nullable null union in struct.
 TEST(UnionTest, Validation_NullUnion_Failure) {
-  Environment environment;
   SmallStructNonNullableUnionPtr small_struct(
       SmallStructNonNullableUnion::New());
 
@@ -560,7 +547,6 @@
 
 // Validation passes with nullable null union.
 TEST(UnionTest, Validation_NullableUnion) {
-  Environment environment;
   SmallStructPtr small_struct(SmallStruct::New());
 
   size_t size = GetSerializedSize_(small_struct);
@@ -596,7 +582,6 @@
 }
 
 TEST(UnionTest, PodUnionInMapSerialization) {
-  Environment environment;
   Map<String, PodUnionPtr> map;
   map.insert("one", PodUnion::New());
   map.insert("two", PodUnion::New());
@@ -621,7 +606,6 @@
 }
 
 TEST(UnionTest, PodUnionInMapSerializationWithNull) {
-  Environment environment;
   Map<String, PodUnionPtr> map;
   map.insert("one", PodUnion::New());
   map.insert("two", nullptr);
@@ -655,7 +639,6 @@
 }
 
 TEST(UnionTest, StructInUnionSerialization) {
-  Environment environment;
   DummyStructPtr dummy(DummyStruct::New());
   dummy->f_int8 = 8;
 
@@ -679,7 +662,6 @@
 }
 
 TEST(UnionTest, StructInUnionValidation) {
-  Environment environment;
   DummyStructPtr dummy(DummyStruct::New());
   dummy->f_int8 = 8;
 
@@ -705,7 +687,6 @@
 }
 
 TEST(UnionTest, StructInUnionValidationNonNullable) {
-  Environment environment;
   DummyStructPtr dummy(nullptr);
 
   ObjectUnionPtr obj(ObjectUnion::New());
@@ -730,7 +711,6 @@
 }
 
 TEST(UnionTest, StructInUnionValidationNullable) {
-  Environment environment;
   DummyStructPtr dummy(nullptr);
 
   ObjectUnionPtr obj(ObjectUnion::New());
@@ -755,8 +735,6 @@
 }
 
 TEST(UnionTest, ArrayInUnionGetterSetter) {
-  Environment environment;
-
   Array<int8_t> array(2);
   array[0] = 8;
   array[1] = 9;
@@ -769,8 +747,6 @@
 }
 
 TEST(UnionTest, ArrayInUnionSerialization) {
-  Environment environment;
-
   Array<int8_t> array(2);
   array[0] = 8;
   array[1] = 9;
@@ -797,8 +773,6 @@
 }
 
 TEST(UnionTest, ArrayInUnionValidation) {
-  Environment environment;
-
   Array<int8_t> array(2);
   array[0] = 8;
   array[1] = 9;
@@ -824,7 +798,6 @@
 }
 
 TEST(UnionTest, MapInUnionGetterSetter) {
-  Environment environment;
   Map<String, int8_t> map;
   map.insert("one", 1);
   map.insert("two", 2);
@@ -837,7 +810,6 @@
 }
 
 TEST(UnionTest, MapInUnionSerialization) {
-  Environment environment;
   Map<String, int8_t> map;
   map.insert("one", 1);
   map.insert("two", 2);
@@ -864,7 +836,6 @@
 }
 
 TEST(UnionTest, MapInUnionValidation) {
-  Environment environment;
   Map<String, int8_t> map;
   map.insert("one", 1);
   map.insert("two", 2);
@@ -903,7 +874,6 @@
 }
 
 TEST(UnionTest, UnionInUnionSerialization) {
-  Environment environment;
   PodUnionPtr pod(PodUnion::New());
   pod->set_f_int8(10);
 
@@ -927,7 +897,6 @@
 }
 
 TEST(UnionTest, UnionInUnionValidation) {
-  Environment environment;
   PodUnionPtr pod(PodUnion::New());
   pod->set_f_int8(10);
 
@@ -954,7 +923,6 @@
 }
 
 TEST(UnionTest, UnionInUnionValidationNonNullable) {
-  Environment environment;
   PodUnionPtr pod(nullptr);
 
   ObjectUnionPtr obj(ObjectUnion::New());
@@ -1028,7 +996,6 @@
 }
 
 TEST(UnionTest, HandleInUnionValidation) {
-  Environment environment;
   ScopedMessagePipeHandle pipe0;
   ScopedMessagePipeHandle pipe1;
 
@@ -1056,7 +1023,6 @@
 }
 
 TEST(UnionTest, HandleInUnionValidationNull) {
-  Environment environment;
   ScopedMessagePipeHandle pipe;
   HandleUnionPtr handle(HandleUnion::New());
   handle->set_f_message_pipe(pipe.Pass());
@@ -1095,8 +1061,7 @@
 };
 
 TEST(UnionTest, InterfaceInUnion) {
-  Environment env;
-  RunLoop run_loop;
+  base::MessageLoop run_loop(common::MessagePumpMojo::Create());
   SmallCacheImpl impl;
   SmallCachePtr ptr;
   Binding<SmallCache> bindings(&impl, GetProxy(&ptr));
@@ -1110,8 +1075,7 @@
 }
 
 TEST(UnionTest, InterfaceInUnionSerialization) {
-  Environment env;
-  RunLoop run_loop;
+  base::MessageLoop run_loop(common::MessagePumpMojo::Create());
   SmallCacheImpl impl;
   SmallCachePtr ptr;
   Binding<SmallCache> bindings(&impl, GetProxy(&ptr));
@@ -1150,8 +1114,7 @@
 };
 
 TEST(UnionTest, UnionInInterface) {
-  Environment env;
-  RunLoop run_loop;
+  base::MessageLoop run_loop(common::MessagePumpMojo::Create());
   UnionInterfaceImpl impl;
   UnionInterfacePtr ptr;
   Binding<UnionInterface> bindings(&impl, GetProxy(&ptr));
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/tests/validation_unittest.cc b/third_party/mojo/src/mojo/public/cpp/bindings/tests/validation_unittest.cc
index 09ee930..fc536c2 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "base/message_loop/message_loop.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/c/system/macros.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_ptr.h"
@@ -18,10 +20,8 @@
 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
 #include "mojo/public/cpp/bindings/message.h"
 #include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h"
-#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/core.h"
 #include "mojo/public/cpp/test_support/test_support.h"
-#include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -185,17 +185,13 @@
   }
 };
 
-class ValidationTest : public testing::Test {
- public:
-  ~ValidationTest() override {}
-
- private:
-  Environment env_;
-};
+using ValidationTest = testing::Test;
 
 class ValidationIntegrationTest : public ValidationTest {
  public:
-  ValidationIntegrationTest() : test_message_receiver_(nullptr) {}
+  ValidationIntegrationTest()
+      : loop_(common::MessagePumpMojo::Create()),
+        test_message_receiver_(nullptr) {}
 
   ~ValidationIntegrationTest() override {}
 
@@ -243,7 +239,7 @@
 
   void PumpMessages() { loop_.RunUntilIdle(); }
 
-  RunLoop loop_;
+  base::MessageLoop loop_;
   TestMessageReceiver* test_message_receiver_;
   ScopedMessagePipeHandle testee_endpoint_;
 };
diff --git a/third_party/mojo/src/mojo/public/mojo_sdk.gni b/third_party/mojo/src/mojo/public/mojo_sdk.gni
index 3f604d3..598b5b4 100644
--- a/third_party/mojo/src/mojo/public/mojo_sdk.gni
+++ b/third_party/mojo/src/mojo/public/mojo_sdk.gni
@@ -123,7 +123,9 @@
           # the Mojo SDK should be on targets within the same file or on a
           # whitelisted set of external dependencies.
           dep_dir = get_path_info(dep, "dir")
-          assert(dep_dir == "." || dep == "//testing/gtest")
+          assert(dep_dir == "." || dep == "//testing/gtest" ||
+                 dep == "//mojo/environment:chromium" ||
+                 dep == "//mojo/message_pump")
         }
         deps += [ dep ]
       }
diff --git a/third_party/polymer/v1_0/README.chromium b/third_party/polymer/v1_0/README.chromium
index 83b2a841..25ba3a3 100644
--- a/third_party/polymer/v1_0/README.chromium
+++ b/third_party/polymer/v1_0/README.chromium
@@ -1,7 +1,7 @@
 Name: Polymer
 Short Name: polymer
 URL: http://www.polymer-project.org
-Version: 1.1.13
+Version: 1.2.1
 Revision: (See components/<component>/.bower.json)
 License: BSD
 License File: ../LICENSE.polymer
diff --git a/third_party/polymer/v1_0/chromium.patch b/third_party/polymer/v1_0/chromium.patch
index 6490201..9b27dc9 100644
--- a/third_party/polymer/v1_0/chromium.patch
+++ b/third_party/polymer/v1_0/chromium.patch
@@ -23,18 +23,3 @@
  },
  removeCustomPropAssignment: function (cssText) {
  return cssText.replace(this._rx.customProp, '').replace(this._rx.mixinProp, '');
-diff --git a/components-chromium/polymer-externs/polymer.externs.js b/components-chromium/polymer-externs/polymer.externs.js
-index e7d685d..0e950f9 100644
---- a/components-chromium/polymer-externs/polymer.externs.js
-+++ b/components-chromium/polymer-externs/polymer.externs.js
-@@ -464,6 +464,9 @@ PolymerElement.prototype.updateStyles = function(properties) {};
-  */
- PolymerElement.prototype.customStyle;
- 
-+/** @type {Node|undefined} */
-+PolymerElement.prototype.shadyRoot;
-+
- /**
-  * Logs a message to the console.
-  *
-
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/.bower.json
index 845de27..4bf4a72b 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-a11y-keys-behavior",
-  "version": "1.0.6",
+  "version": "1.0.8",
   "description": "A behavior that enables keybindings for greater a11y.",
   "keywords": [
     "web-components",
@@ -30,11 +30,11 @@
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
   "homepage": "https://github.com/PolymerElements/iron-a11y-keys-behavior",
-  "_release": "1.0.6",
+  "_release": "1.0.8",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.6",
-    "commit": "af5c98b1cf9b3d180a6326c99ac9c7057eee647f"
+    "tag": "v1.0.8",
+    "commit": "df29a9edcff3b4693707f1e3eebce5a1dc46e946"
   },
   "_source": "git://github.com/PolymerElements/iron-a11y-keys-behavior.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/bower.json b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/bower.json
index 3d53ecf..623d471 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-a11y-keys-behavior",
-  "version": "1.0.6",
+  "version": "1.0.8",
   "description": "A behavior that enables keybindings for greater a11y.",
   "keywords": [
     "web-components",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js
index 423c6df..175ed24 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior-extracted.js
@@ -242,6 +242,15 @@
           }
         },
 
+        /**
+         * If true, this property will cause the implementing element to
+         * automatically stop propagation on any handled KeyboardEvents.
+         */
+        stopKeyboardEventPropagation: {
+          type: Boolean,
+          value: false
+        },
+
         _boundKeyHandlers: {
           type: Array,
           value: function() {
@@ -385,6 +394,10 @@
       },
 
       _onKeyBindingEvent: function(keyBindings, event) {
+        if (this.stopKeyboardEventPropagation) {
+          event.stopPropagation();
+        }
+
         keyBindings.forEach(function(keyBinding) {
           var keyCombo = keyBinding[0];
           var handlerName = keyBinding[1];
@@ -398,10 +411,14 @@
       _triggerKeyHandler: function(keyCombo, handlerName, keyboardEvent) {
         var detail = Object.create(keyCombo);
         detail.keyboardEvent = keyboardEvent;
-
-        this[handlerName].call(this, new CustomEvent(keyCombo.event, {
-          detail: detail
-        }));
+        var event = new CustomEvent(keyCombo.event, {
+          detail: detail,
+          cancelable: true
+        });
+        this[handlerName].call(this, event);
+        if (event.defaultPrevented) {
+          keyboardEvent.preventDefault();
+        }
       }
     };
   })();
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/.bower.json
index 002aa8f..b7650ad 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-a11y-keys",
-  "version": "1.0.2",
+  "version": "1.0.3",
   "description": "A basic element implementation of iron-a11y-keys-behavior, matching the legacy core-a11y-keys.",
   "keywords": [
     "web-components",
@@ -31,11 +31,11 @@
     "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0"
   },
   "homepage": "https://github.com/PolymerElements/iron-a11y-keys",
-  "_release": "1.0.2",
+  "_release": "1.0.3",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.2",
-    "commit": "7a53ab4824ee61ab994abfa8b5a3e1ad2ff9655d"
+    "tag": "v1.0.3",
+    "commit": "823d3dd6a9688fefae8bd351b49667c0f01e1569"
   },
   "_source": "git://github.com/PolymerElements/iron-a11y-keys.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/.travis.yml b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/.travis.yml
new file mode 100644
index 0000000..fc9f77f5
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: GYOQylogyw3LQdQ+65plW6DKXBklQm4M72U6UuaEu+e12QB7DGcWPhrDko7c7uc3DNVHFWzOw4r4DUAgMZM/7+ifTW6ARnXcu/FWfhVqRRjEpgSenMFo+QRjM5VmCuIqVlXV+tz+PXhBd9M/4TYOs8Tu+caCrSAD0SfLXV+FEZjqno6xYiZvW9xpvMWRE+hlDjV1JWEb6drxR8yhykDdByRQ1F0xbR/QzQXQe6fvDWTjwV7XIketFhfl5cQWESWJPhKMOf6DmJsoZojTpD3kcNlRGiC72SSlk5WukKdP2Bkt0MADxw4VyqoGWwXaIJxy+/bQe3nwZKCTlv+xGVRZyyqTeeHBjB9UDABq9KpJVBydAvrCoXYK+avUGsPE835hdoojwU8hbAAVLPFCRGvyXZ8Yvqq+FHnf2kb6iGakJOt4KA6GzaloBpj9FlZIcha/Q6iDQJ/Ec9YFwMVzutLAWok47u+QNWXe8TW7PPXleGhUjZID5bUKjKnKleHdVW05x/mXpmt1FYUuK7fD7klUEEg5lNtHO4WBBtmuns4iVv6BGgjjLuElqqzC1Lx69i0Bmh8bL5WV9n04/xJ701J+WATqdrGH2DyR2DwgCMbfHiQzyIQhpySTzcaYW9v87ZjojqZ5VAHO99JLPJVRfrm/Lh6RzDHq7Vn7azUoOcEnybM=
+  - secure: e+QHe/dcItz7qPotuYi2Pm1BlaEKIjTnUiUmB2KAu7nUzZD1sYwI29/XCX+cueDmlMibrWOnuZBrhG0/dyYU8oLDFu9F6E81K0jnNkhI4NXAPrwL58uEbsSKtf9FLYTWDRmik/vjarUEwdtx8kwCG6t9ynZLH1wiiLdJ/j+TGGRXxUePysIsAo/urEOEutnfsRR7E+tPE7hMbCZnHyJ9xYp/VbuXI7tvLoRrAfcIh19ZMCNKHlT2Gnl0jw5nlidNVm8zrMnl4ZTYa9mnqGvcZkVtZhAjcLPwUQ1xL/viXs0qj8u8hy135EpWoRcKJJviksMErIfBGreACsx+D5E3g5ZVrYdaFjx5f3MsjTpbyfC4/ZsqRFePkVLxS+hPZg9/HzwQI/v+YrTEpTWY5Xb/ZsMqCmAWNJGt1+c72dhLlRYb5Cb7UV6qqnYWNbgO12c3FZ9qPWnCteyFofqQt82OwU1osALBDGdKsmjiiWEzVxPoLe4C73dIiZdW84+6KZNECkN5zFBwKBzc7UuYFKWObQGc6KTSJccFXKaEqwmWXI/2qKTq8gvoXrRfZ4Bm8vFUuRxPgnl83CAMM7GE08+svHycPof1ZVEVNdo6cLw5dABqd2A1t2CCCJGTJyeL0w3wm4m8ZnK0HFY7z3TBIFUniD3UyDOWoF8gfo9R5evSoLM=
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/README.md b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/README.md
index 514b4f5..426c46d8 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/README.md
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/README.md
@@ -1,3 +1,130 @@
-iron-a11y-keys
-==============
+
+<!---
+
+This README is automatically generated from the comments in these files:
+iron-a11y-keys.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/iron-a11y-keys.svg?branch=master)](https://travis-ci.org/PolymerElements/iron-a11y-keys)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/iron-a11y-keys)_
+
+
+##&lt;iron-a11y-keys&gt;
+
+
+`iron-a11y-keys` provides a cross-browser interface for processing 
+keyboard commands. The interface adheres to [WAI-ARIA best 
+practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding). 
+It uses an expressive syntax to filter key presses.
+
+## Basic usage
+
+The sample code below is a portion of a custom element. The goal is to call
+the `onEnter` method whenever the `paper-input` element is in focus and 
+the `Enter` key is pressed.
+
+    <iron-a11y-keys id="a11y" target="[[target]]" keys="enter"
+                        on-keys-pressed="onEnter"></iron-a11y-keys>
+    <paper-input id="input"
+                 placeholder="Type something. Press enter. Check console."
+                 value="{{userInput::input}}"></paper-input>
+
+The custom element declares an `iron-a11y-keys` element that is bound to a 
+property called `target`. The `target` property
+needs to evaluate to the `paper-input` node. `iron-a11y-keys` registers 
+an event handler for the target node using Polymer's [annotated event handler
+syntax](https://www.polymer-project.org/1.0/docs/devguide/events.html#annotated-listeners). `{{userInput::input}}` sets the `userInput` property to the 
+user's input on each keystroke. 
+
+The last step is to link the two elements within the custom element's 
+registration.
+
+    ...
+    properties: {
+      userInput: {
+        type: String,
+        notify: true,
+      },
+      target: {
+        type: Object,
+        value: function() {
+          return this.$.input;
+        }
+      },
+    },
+    onEnter: function() {
+      console.log(this.userInput);
+    }
+    ...
+
+## The `keys` attribute
+
+The `keys` attribute expresses what combination of keys triggers the event.
+
+The attribute accepts a space-separated, plus-sign-concatenated 
+set of modifier keys and some common keyboard keys.
+
+The common keys are: `a-z`, `0-9` (top row and number pad), `*` (shift 8 and 
+number pad), `F1-F12`, `Page Up`, `Page Down`, `Left Arrow`, `Right Arrow`,
+`Down Arrow`, `Up Arrow`, `Home`, `End`, `Escape`, `Space`, `Tab`, `Enter`.
+
+The modifier keys are: `Shift`, `Control`, `Alt`.
+
+All keys are expected to be lowercase and shortened. E.g.
+`Left Arrow` is `left`, `Page Down` is `pagedown`, `Control` is `ctrl`, 
+`F1` is `f1`, `Escape` is `esc`, etc.
+
+### Grammar
+
+Below is the [EBNF](http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form) 
+Grammar of the `keys` attribute.
+
+    modifier = "shift" | "ctrl" | "alt";
+    ascii = ? /[a-z0-9]/ ? ;
+    fnkey = ? f1 through f12 ? ;
+    arrow = "up" | "down" | "left" | "right" ;
+    key = "tab" | "esc" | "space" | "*" | "pageup" | "pagedown" | 
+          "home" | "end" | arrow | ascii | fnkey;
+    keycombo = { modifier, "+" }, key ;
+    keys = keycombo, { " ", keycombo } ;
+
+### Example
+
+Given the following value for `keys`: 
+
+`ctrl+shift+f7 up pagedown esc space alt+m`
+
+The event is fired if any of the following key combinations are fired: 
+`Control` and `Shift` and `F7` keys, `Up Arrow` key, `Page Down` key, 
+`Escape` key, `Space` key, `Alt` and `M` keys.
+
+### WAI-ARIA Slider Example
+
+The following is an example of the set of keys that fulfills WAI-ARIA's 
+"slider" role [best
+practices](http://www.w3.org/TR/wai-aria-practices/#slider):
+
+    <iron-a11y-keys target="[[target]]" keys="left pagedown down" 
+                    on-keys-pressed="decrement"></iron-a11y-keys>
+    <iron-a11y-keys target=""[[target]] keys="right pageup up" 
+                    on-keys-pressed="increment"></iron-a11y-keys>
+    <iron-a11y-keys target="[[target]]" keys="home" 
+                    on-keys-pressed="setMin"></iron-a11y-keys>
+    <iron-a11y-keys target=""[[target]] keys="end" 
+                    on-keys-pressed="setMax"></iron-a11y-keys>
+
+The `target` properties must evaluate to a node. See the basic usage 
+example above.
+
+Each of the values for the `on-keys-pressed` attributes must evalute
+to methods. The `increment` method should move the slider a set amount 
+toward the maximum value. `decrement` should move the slider a set amount 
+toward the minimum value. `setMin` should move the slider to the minimum 
+value. `setMax` should move the slider to the maximum value.
+
 
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/bower.json b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/bower.json
index 11c28c3..00dc447 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-a11y-keys",
-  "version": "1.0.2",
+  "version": "1.0.3",
   "description": "A basic element implementation of iron-a11y-keys-behavior, matching the legacy core-a11y-keys.",
   "keywords": [
     "web-components",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/iron-a11y-keys-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/iron-a11y-keys-extracted.js
index 477f6f1..2b46b92 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/iron-a11y-keys-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/iron-a11y-keys-extracted.js
@@ -1,66 +1,114 @@
-
-
 /*
-`iron-a11y-keys` provides a normalized interface for processing keyboard commands that pertain to [WAI-ARIA best
-practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding). The element takes care of browser differences
-with respect to Keyboard events and uses an expressive syntax to filter key presses.
+`iron-a11y-keys` provides a cross-browser interface for processing 
+keyboard commands. The interface adheres to [WAI-ARIA best 
+practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding). 
+It uses an expressive syntax to filter key presses.
 
-Use the `keys` attribute to express what combination of keys will trigger the event to fire.
+## Basic usage
 
-Use the `target` attribute to set up event handlers on a specific node.
-The `keys-pressed` event will fire when one of the key combinations set with the `keys` attribute is pressed.
+The sample code below is a portion of a custom element. The goal is to call
+the `onEnter` method whenever the `paper-input` element is in focus and 
+the `Enter` key is pressed.
 
-Example:
+    <iron-a11y-keys id="a11y" target="[[target]]" keys="enter"
+                        on-keys-pressed="onEnter"></iron-a11y-keys>
+    <paper-input id="input"
+                 placeholder="Type something. Press enter. Check console."
+                 value="{{userInput::input}}"></paper-input>
 
-This element will call `arrowHandler` on all arrow keys:
+The custom element declares an `iron-a11y-keys` element that is bound to a 
+property called `target`. The `target` property
+needs to evaluate to the `paper-input` node. `iron-a11y-keys` registers 
+an event handler for the target node using Polymer's [annotated event handler
+syntax](https://www.polymer-project.org/1.0/docs/devguide/events.html#annotated-listeners). `{{userInput::input}}` sets the `userInput` property to the 
+user's input on each keystroke. 
 
-    <iron-a11y-keys target="{{}}" keys="up down left right" on-keys-pressed="{{arrowHandler}}"></iron-a11y-keys>
+The last step is to link the two elements within the custom element's 
+registration.
 
-Keys Syntax:
+    ...
+    properties: {
+      userInput: {
+        type: String,
+        notify: true,
+      },
+      target: {
+        type: Object,
+        value: function() {
+          return this.$.input;
+        }
+      },
+    },
+    onEnter: function() {
+      console.log(this.userInput);
+    }
+    ...
 
-The `keys` attribute can accepts a space seprated, `+` concatenated set of modifier keys and some common keyboard keys.
+## The `keys` attribute
 
-The common keys are `a-z`, `0-9` (top row and number pad), `*` (shift 8 and number pad), `F1-F12`, `Page Up`, `Page
-Down`, `Left Arrow`, `Right Arrow`, `Down Arrow`, `Up Arrow`, `Home`, `End`, `Escape`, `Space`, `Tab`, and `Enter` keys.
+The `keys` attribute expresses what combination of keys triggers the event.
 
-The modifier keys are `Shift`, `Control`, and `Alt`.
+The attribute accepts a space-separated, plus-sign-concatenated 
+set of modifier keys and some common keyboard keys.
 
-All keys are expected to be lowercase and shortened:
-`Left Arrow` is `left`, `Page Down` is `pagedown`, `Control` is `ctrl`, `F1` is `f1`, `Escape` is `esc` etc.
+The common keys are: `a-z`, `0-9` (top row and number pad), `*` (shift 8 and 
+number pad), `F1-F12`, `Page Up`, `Page Down`, `Left Arrow`, `Right Arrow`,
+`Down Arrow`, `Up Arrow`, `Home`, `End`, `Escape`, `Space`, `Tab`, `Enter`.
 
-Keys Syntax Example:
+The modifier keys are: `Shift`, `Control`, `Alt`.
 
-Given the `keys` attribute value "ctrl+shift+f7 up pagedown esc space alt+m", the `<iron-a11y-keys>` element will send
-the `keys-pressed` event if any of the follow key combos are pressed: Control and Shift and F7 keys, Up Arrow key, Page
-Down key, Escape key, Space key, Alt and M key.
+All keys are expected to be lowercase and shortened. E.g.
+`Left Arrow` is `left`, `Page Down` is `pagedown`, `Control` is `ctrl`, 
+`F1` is `f1`, `Escape` is `esc`, etc.
 
-Slider Example:
+### Grammar
 
-The following is an example of the set of keys that fulfil the WAI-ARIA "slider" role [best
-practices](http://www.w3.org/TR/wai-aria-practices/#slider):
-
-    <iron-a11y-keys target="{{}}" keys="left pagedown down" on-keys-pressed="{{decrement}}"></iron-a11y-keys>
-    <iron-a11y-keys target="{{}}" keys="right pageup up" on-keys-pressed="{{increment}}"></iron-a11y-keys>
-    <iron-a11y-keys target="{{}}" keys="home" on-keys-pressed="{{setMin}}"></iron-a11y-keys>
-    <iron-a11y-keys target="{{}}" keys="end" on-keys-pressed="{{setMax}}"></iron-a11y-keys>
-
-The `increment` function will move the slider a set amount toward the maximum value.
-The `decrement` function will move the slider a set amount toward the minimum value.
-The `setMin` function will move the slider to the minimum value.
-The `setMax` function will move the slider to the maximum value.
-
-Keys Syntax Grammar:
-
-[EBNF](http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form) Grammar of the `keys` attribute.
+Below is the [EBNF](http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form) 
+Grammar of the `keys` attribute.
 
     modifier = "shift" | "ctrl" | "alt";
     ascii = ? /[a-z0-9]/ ? ;
     fnkey = ? f1 through f12 ? ;
     arrow = "up" | "down" | "left" | "right" ;
-    key = "tab" | "esc" | "space" | "*" | "pageup" | "pagedown" | "home" | "end" | arrow | ascii | fnkey ;
+    key = "tab" | "esc" | "space" | "*" | "pageup" | "pagedown" | 
+          "home" | "end" | arrow | ascii | fnkey;
     keycombo = { modifier, "+" }, key ;
     keys = keycombo, { " ", keycombo } ;
 
+### Example
+
+Given the following value for `keys`: 
+
+`ctrl+shift+f7 up pagedown esc space alt+m`
+
+The event is fired if any of the following key combinations are fired: 
+`Control` and `Shift` and `F7` keys, `Up Arrow` key, `Page Down` key, 
+`Escape` key, `Space` key, `Alt` and `M` keys.
+
+### WAI-ARIA Slider Example
+
+The following is an example of the set of keys that fulfills WAI-ARIA's 
+"slider" role [best
+practices](http://www.w3.org/TR/wai-aria-practices/#slider):
+
+    <iron-a11y-keys target="[[target]]" keys="left pagedown down" 
+                    on-keys-pressed="decrement"></iron-a11y-keys>
+    <iron-a11y-keys target=""[[target]] keys="right pageup up" 
+                    on-keys-pressed="increment"></iron-a11y-keys>
+    <iron-a11y-keys target="[[target]]" keys="home" 
+                    on-keys-pressed="setMin"></iron-a11y-keys>
+    <iron-a11y-keys target=""[[target]] keys="end" 
+                    on-keys-pressed="setMax"></iron-a11y-keys>
+
+The `target` properties must evaluate to a node. See the basic usage 
+example above.
+
+Each of the values for the `on-keys-pressed` attributes must evalute
+to methods. The `increment` method should move the slider a set amount 
+toward the maximum value. `decrement` should move the slider a set amount 
+toward the minimum value. `setMin` should move the slider to the minimum 
+value. `setMax` should move the slider to the maximum value.
+
 @demo demo/index.html
 */
 
@@ -104,4 +152,4 @@
     _fireKeysPressed: function(event) {
       this.fire('keys-pressed', event.detail, {});
     }
-  });
+  });
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/iron-a11y-keys.html b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/iron-a11y-keys.html
index 6e6a8d8e..0952980 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/iron-a11y-keys.html
+++ b/third_party/polymer/v1_0/components-chromium/iron-a11y-keys/iron-a11y-keys.html
@@ -9,5 +9,4 @@
 --><html><head><link rel="import" href="../polymer/polymer.html">
 <link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
 
-
 </head><body><script src="iron-a11y-keys-extracted.js"></script></body></html>
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/.bower.json
index 2533391c..e732fcc 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-autogrow-textarea",
-  "version": "1.0.7",
+  "version": "1.0.8",
   "description": "A textarea element that automatically grows with input",
   "authors": [
     "The Polymer Authors"
@@ -37,11 +37,11 @@
     "paper-styles": "PolymerElements/paper-styles#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.7",
+  "_release": "1.0.8",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.7",
-    "commit": "f31131a9c45af7845780f94ec7e69816929ac6cc"
+    "tag": "v1.0.8",
+    "commit": "ea7fb14d8038ccbedc6e85b9c4842b68c659a503"
   },
   "_source": "git://github.com/PolymerElements/iron-autogrow-textarea.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/bower.json b/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/bower.json
index 278baba..8fdbca8 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-autogrow-textarea",
-  "version": "1.0.7",
+  "version": "1.0.8",
   "description": "A textarea element that automatically grows with input",
   "authors": [
     "The Polymer Authors"
diff --git a/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/iron-autogrow-textarea-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/iron-autogrow-textarea-extracted.js
index f0c8b0fb..6bec3180 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/iron-autogrow-textarea-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/iron-autogrow-textarea-extracted.js
@@ -12,6 +12,8 @@
 
       /**
        * Use this property instead of `value` for two-way data binding.
+       *
+       * @type {string|number|undefined|null}
        */
       bindValue: {
         observer: '_bindValueChanged',
@@ -215,7 +217,8 @@
       while (this.rows > 0 && _tokens.length < this.rows) {
         _tokens.push('');
       }
-      return _tokens.join('<br>') + '&nbsp;';
+      // Use &#160; instead &nbsp; of to allow this element to be used in XHTML.
+      return _tokens.join('<br/>') + '&#160;';
     },
 
     _valueForMirror: function() {
diff --git a/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/iron-autogrow-textarea.html b/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/iron-autogrow-textarea.html
index dbb8708..c837d21 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/iron-autogrow-textarea.html
+++ b/third_party/polymer/v1_0/components-chromium/iron-autogrow-textarea/iron-autogrow-textarea.html
@@ -8,7 +8,7 @@
 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 --><html><head><link rel="import" href="../polymer/polymer.html">
 <link rel="import" href="../iron-behaviors/iron-control-state.html">
-<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
 <link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.html">
 <link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
 
@@ -53,6 +53,10 @@
       word-wrap: break-word;
     }
 
+    .fit {
+      @apply(--layout-fit);
+    }
+
     textarea {
       position: relative;
       outline: none;
@@ -66,6 +70,7 @@
       font-size: inherit;
       font-family: inherit;
       line-height: inherit;
+      text-align: inherit;
       @apply(--iron-autogrow-textarea);
     }
 
@@ -76,6 +81,7 @@
   </style>
   <template>
     <!-- the mirror sizes the input/textarea so it grows with typing -->
+    <!-- use &#160; instead &nbsp; of to allow this element to be used in XHTML -->
     <div id="mirror" class="mirror-text" aria-hidden="true">&nbsp;</div>
 
     <!-- size the input/textarea with a div, because the textarea has intrinsic size in ff -->
diff --git a/third_party/polymer/v1_0/components-chromium/iron-behaviors/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-behaviors/.bower.json
index 9ce976f..79061c0e 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-behaviors/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-behaviors/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-behaviors",
-  "version": "1.0.9",
+  "version": "1.0.10",
   "description": "Provides a set of behaviors for the iron elements",
   "private": true,
   "authors": [
@@ -28,11 +28,11 @@
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
   "homepage": "https://github.com/PolymerElements/iron-behaviors",
-  "_release": "1.0.9",
+  "_release": "1.0.10",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.9",
-    "commit": "4b8cab62a4916cc4b1dbd262cbb7eb1eec624b6f"
+    "tag": "v1.0.10",
+    "commit": "da937a6c5841fc9dba57f3087083445c9ad709a8"
   },
   "_source": "git://github.com/PolymerElements/iron-behaviors.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-behaviors/.travis.yml b/third_party/polymer/v1_0/components-chromium/iron-behaviors/.travis.yml
new file mode 100644
index 0000000..e873af2
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-behaviors/.travis.yml
@@ -0,0 +1,30 @@
+language: node_js
+sudo: false
+cache:
+  directories:
+  - node_modules
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run -a wct --simpleOutput -l firefox -l chrome
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct --simpleOutput -s 'Windows 10/microsoftedge' -s 'Windows 8.1/internet explorer@11' -s 'Windows 7/internet explorer@10' -s 'OS X 10.10/safari@8' -s 'OS X 10.9/safari@7'
+      fi
+before_script:
+- npm install bower web-component-tester
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: ZOqj2XVNVwfT74rHxg/ljcAsS6FnmDpRSsXbsy1Icv9DcLHrMlmyQ10gWBjE/YXYF0Uv4akQ1qqn0TJaKOtp9HZeH+P6OPAYk2vJbWD7qp52pPtIqEFomcsUyflt4IjfaXKuN4FMod7PSWVSGJ+DxSguJvZKILkrs5d/rJdFv3c=
+  - secure: clkqemGQG16TXyAPkv9LBv6x3SbT3ZM0eo8LETx4uNKi3WzlwgXxZA9b5Sr5wYzxyxFFpnhDXW7CL4+UjYu1atGNeTW2TuSaYUPHtgu67OFDr8Jbw047p1XQb5enPSt9+YxrHKfjHBiJvWulJ8rCSQshU9Rhe0DC6NrFRPFgk0A=
diff --git a/third_party/polymer/v1_0/components-chromium/iron-behaviors/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/iron-behaviors/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-behaviors/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/iron-behaviors/README.md b/third_party/polymer/v1_0/components-chromium/iron-behaviors/README.md
index 593986e..6b39f8bb 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-behaviors/README.md
+++ b/third_party/polymer/v1_0/components-chromium/iron-behaviors/README.md
@@ -1,4 +1,19 @@
-iron-behaviors
-==============
 
-This repository collects shared behaviors that are mixed in to other elements.
+<!---
+
+This README is automatically generated from the comments in these files:
+iron-button-state.html  iron-control-state.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/iron-behaviors.svg?branch=master)](https://travis-ci.org/PolymerElements/iron-behaviors)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/iron-behaviors)_
+
+
+<!-- No docs for Polymer.IronControlState found. -->
+
+<!-- No docs for Polymer.IronButtonState found. -->
diff --git a/third_party/polymer/v1_0/components-chromium/iron-behaviors/bower.json b/third_party/polymer/v1_0/components-chromium/iron-behaviors/bower.json
index a7f622b..e001c7f 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-behaviors/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-behaviors/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-behaviors",
-  "version": "1.0.9",
+  "version": "1.0.10",
   "description": "Provides a set of behaviors for the iron elements",
   "private": true,
   "authors": [
diff --git a/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js
index 1b9a5ad9..936987f 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-button-state-extracted.js
@@ -120,14 +120,43 @@
       this._setPressed(false);
     },
 
+    __isFocusedLightDescendant: function(target) {
+      var root = Polymer.dom(this).getOwnerRoot() || document;
+      var focusedElement = root.activeElement;
+
+      // TODO(noms): remove the `this !== target` check once polymer#2610 is fixed.
+      return this !== target && this.isLightDescendant(target) && target == focusedElement;
+    },
+
+    /**
+     * @param {!KeyboardEvent} event .
+     */
     _spaceKeyDownHandler: function(event) {
       var keyboardEvent = event.detail.keyboardEvent;
+      var target = Polymer.dom(keyboardEvent).localTarget;
+
+      // Ignore the event if this is coming from a focused light child, since that
+      // element will deal with it.
+      if (this.__isFocusedLightDescendant(target))
+        return;
+
       keyboardEvent.preventDefault();
       keyboardEvent.stopImmediatePropagation();
       this._setPressed(true);
     },
 
-    _spaceKeyUpHandler: function() {
+    /**
+     * @param {!KeyboardEvent} event .
+     */
+    _spaceKeyUpHandler: function(event) {
+      var keyboardEvent = event.detail.keyboardEvent;
+      var target = Polymer.dom(keyboardEvent).localTarget;
+
+      // Ignore the event if this is coming from a focused light child, since that
+      // element will deal with it.
+      if (this.__isFocusedLightDescendant(target))
+        return;
+
       if (this.pressed) {
         this._asyncClick();
       }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js
index e5dc06b..72f8088 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-behaviors/iron-control-state-extracted.js
@@ -58,9 +58,8 @@
       // handled). In either case, we can disregard `event.path`.
 
       if (event.target === this) {
-        var focused = event.type === 'focus';
-        this._setFocused(focused);
-      } else if (!this.shadowRoot) {
+        this._setFocused(event.type === 'focus');
+      } else if (!this.shadowRoot && !this.isLightDescendant(event.target)) {
         this.fire(event.type, {sourceEvent: event}, {
           node: this,
           bubbles: event.bubbles,
diff --git a/third_party/polymer/v1_0/components-chromium/iron-collapse/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-collapse/.bower.json
index 2eecb886..2a3d0332 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-collapse/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-collapse/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-collapse",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "description": "Provides a collapsable container",
   "authors": [
     "The Polymer Authors"
@@ -28,11 +28,11 @@
     "paper-styles": "PolymerElements/paper-styles#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.3",
+  "_release": "1.0.4",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.3",
-    "commit": "08716fe08adec031ecbcfffd1811d27fea2f82ad"
+    "tag": "v1.0.4",
+    "commit": "10cd9980f7198b39bec7aa5bb7f9c7c6357bb467"
   },
   "_source": "git://github.com/PolymerElements/iron-collapse.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-collapse/bower.json b/third_party/polymer/v1_0/components-chromium/iron-collapse/bower.json
index f0438df..3fe807b3 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-collapse/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-collapse/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-collapse",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "description": "Provides a collapsable container",
   "authors": [
     "The Polymer Authors"
diff --git a/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse-extracted.js
index f0ee242..99945f9b 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-collapse/iron-collapse-extracted.js
@@ -82,6 +82,9 @@
 
     _openedChanged: function() {
       if (this.opened) {
+        this.setAttribute('aria-expanded', 'true');
+        this.setAttribute('aria-hidden', 'false');
+
         this.toggleClass('iron-collapse-closed', false);
         this.updateSize('auto', false);
         var s = this._calcSize();
@@ -89,16 +92,18 @@
         // force layout to ensure transition will go
         /** @suppress {suspiciousCode} */ this.offsetHeight;
         this.updateSize(s, true);
-      }
-      else {
+        // focus the current collapse
+        this.focus();
+      } else {
+        this.setAttribute('aria-expanded', 'false');
+        this.setAttribute('aria-hidden', 'true');
+
         this.toggleClass('iron-collapse-opened', false);
         this.updateSize(this._calcSize(), false);
         // force layout to ensure transition will go
         /** @suppress {suspiciousCode} */ this.offsetHeight;
         this.updateSize('0px', true);
       }
-      this.setAttribute('aria-expanded', this.opened ? 'true' : 'false');
-
     },
 
     _transitionEnd: function() {
diff --git a/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/.bower.json
index 3723391..fe5067c 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/.bower.json
@@ -1,12 +1,10 @@
 {
   "name": "iron-fit-behavior",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "license": "http://polymer.github.io/LICENSE.txt",
   "description": "Fits an element inside another element",
   "private": true,
-  "main": [
-    "iron-fit-behavior.html"
-  ],
+  "main": "iron-fit-behavior.html",
   "keywords": [
     "web-components",
     "polymer",
@@ -30,11 +28,11 @@
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
   "homepage": "https://github.com/PolymerElements/iron-fit-behavior",
-  "_release": "1.0.3",
+  "_release": "1.0.4",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.3",
-    "commit": "df9fd83577ea6ebd98f5cad8333daa73dd0f34ba"
+    "tag": "v1.0.4",
+    "commit": "db76c6b9f3df86ee6dfc2339975313ac2efc6474"
   },
   "_source": "git://github.com/PolymerElements/iron-fit-behavior.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/bower.json b/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/bower.json
index 3878165f..f795545 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/bower.json
@@ -1,12 +1,10 @@
 {
   "name": "iron-fit-behavior",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "license": "http://polymer.github.io/LICENSE.txt",
   "description": "Fits an element inside another element",
   "private": true,
-  "main": [
-    "iron-fit-behavior.html"
-  ],
+  "main": "iron-fit-behavior.html",
   "keywords": [
     "web-components",
     "polymer",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/iron-fit-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/iron-fit-behavior-extracted.js
index 8ef6b4a..e6ebe2e 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/iron-fit-behavior-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-fit-behavior/iron-fit-behavior-extracted.js
@@ -193,6 +193,10 @@
       if (!this._fitInfo.positionedBy.horizontally) {
         this.style.left = '0px';
       }
+      if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy.horizontally) {
+        // need position:fixed to properly size the element
+        this.style.position = 'fixed';
+      }
       // need border-box for margin/padding
       this.sizingTarget.style.boxSizing = 'border-box';
       // constrain the width and height if not already set
diff --git a/third_party/polymer/v1_0/components-chromium/iron-flex-layout/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/.bower.json
index 1f8ab2ef..49f7c426 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-flex-layout/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-flex-layout",
-  "version": "1.0.4",
+  "version": "1.0.5",
   "description": "Provide flexbox-based layouts",
   "keywords": [
     "web-components",
@@ -22,15 +22,17 @@
   },
   "devDependencies": {
     "paper-styles": "polymerelements/paper-styles#^1.0.0",
+    "marked-element": "polymerelements/marked-element#^1.0.0",
+    "prism-element": "PolymerElements/prism-element#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
     "iron-component-page": "polymerelements/iron-component-page#^1.0.0"
   },
   "homepage": "https://github.com/PolymerElements/iron-flex-layout",
-  "_release": "1.0.4",
+  "_release": "1.0.5",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.4",
-    "commit": "dcfc54b0d358269bf0c72180b4ab090fc4931ecd"
+    "tag": "v1.0.5",
+    "commit": "00daa8acc95fe53d7cbbe5f9059241c4648ff22e"
   },
   "_source": "git://github.com/PolymerElements/iron-flex-layout.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-flex-layout/.travis.yml b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/.travis.yml
new file mode 100644
index 0000000..b3f20a9
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: jFaXkmco40NlJT4VyFYM34Zv9D1XVfLXgixobnyHQyJDBKSXrNLcwDuvrGUpJx/pwBCxEhKAbvxeJ+PBMUv8QV08MAdw2S6QOsIe3CUxAehoNoOMJw5duhE8faWlz8qzmCWEowHVFUeVsd0ZUsgOu6RTspj2A51D/CztQuW0Ljw=
+  - secure: fKrO5yMx8kZM1WQ3k0bzo6MCREKGW2WkCl2suDjuEtb1SQ/SaZa9Tun0fcqIHVJqg9+jOS1Romt/+MN27Nc6IT1tv/NdLd+uWjtMA+OzLyv48gzcdu8Ls/TISUGm5Wb7XHkcvMAb1tRoBs5BOvQ/85FilZLEq1km8snG9ZsOOWI=
diff --git a/third_party/polymer/v1_0/components-chromium/iron-flex-layout/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/iron-flex-layout/README.md b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/README.md
index 895ed0fe..3651696 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-flex-layout/README.md
+++ b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/README.md
@@ -1,4 +1,28 @@
-iron-flex-layout
-================
 
-Layout styles for the iron elements.
+<!---
+
+This README is automatically generated from the comments in these files:
+iron-flex-layout.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/iron-flex-layout.svg?branch=master)](https://travis-ci.org/PolymerElements/iron-flex-layout)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/iron-flex-layout)_
+
+
+##&lt;iron-flex-layout&gt;
+
+
+The `<iron-flex-layout>` component provides simple ways to use [CSS flexible box layout](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes), also known as flexbox. This component provides two different ways to use flexbox:
+
+1. [Layout classes](https://github.com/PolymerElements/iron-flex-layout/tree/master/classes). The layout class stylesheet provides a simple set of class-based flexbox rules. Layout classes let you specify layout properties directly in markup.
+
+2. [Custom CSS mixins](https://github.com/PolymerElements/iron-flex-layout/blob/master/iron-flex-layout.html). The mixin stylesheet includes custom CSS mixins that can be applied inside a CSS rule using the `@apply` function.
+
+A complete [guide](https://elements.polymer-project.org/guides/flex-layout) to `<iron-flex-layout>` is available.
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/iron-flex-layout/bower.json b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/bower.json
index 42bd9bd..da26e31 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-flex-layout/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-flex-layout/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-flex-layout",
-  "version": "1.0.4",
+  "version": "1.0.5",
   "description": "Provide flexbox-based layouts",
   "keywords": [
     "web-components",
@@ -22,6 +22,8 @@
   },
   "devDependencies": {
     "paper-styles": "polymerelements/paper-styles#^1.0.0",
+    "marked-element": "polymerelements/marked-element#^1.0.0",
+    "prism-element": "PolymerElements/prism-element#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
     "iron-component-page": "polymerelements/iron-component-page#^1.0.0"
   }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/.bower.json
index c588d70..6404c4ce 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-form-element-behavior",
-  "version": "1.0.4",
+  "version": "1.0.5",
   "license": "http://polymer.github.io/LICENSE.txt",
   "private": true,
   "main": [
@@ -30,11 +30,11 @@
     "paper-styles": "PolymerElements/paper-styles#^1.0.0"
   },
   "homepage": "https://github.com/PolymerElements/iron-form-element-behavior",
-  "_release": "1.0.4",
+  "_release": "1.0.5",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.4",
-    "commit": "d5b296d63fa65cc3870c50801e37ffc08fe2d5e3"
+    "tag": "v1.0.5",
+    "commit": "52b16e14511a4b659658da705f5f4b2b45131941"
   },
   "_source": "git://github.com/PolymerElements/iron-form-element-behavior.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/bower.json b/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/bower.json
index 8fc885f..62df8f26 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-form-element-behavior",
-  "version": "1.0.4",
+  "version": "1.0.5",
   "license": "http://polymer.github.io/LICENSE.txt",
   "private": true,
   "main": [
diff --git a/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/iron-form-element-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/iron-form-element-behavior-extracted.js
index 051050ba..640842c 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/iron-form-element-behavior-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-form-element-behavior/iron-form-element-behavior-extracted.js
@@ -40,8 +40,8 @@
        * custom element that uses this behavior should also use
        * Polymer.IronValidatableBehavior and define a custom validation method.
        * Otherwise, a `required` element will always be considered valid.
-       * It's also strongly recomended to provide a visual style for the element
-       * when it's value is invalid.
+       * It's also strongly recommended to provide a visual style for the element
+       * when its value is invalid.
        */
       required: {
         type: Boolean,
diff --git a/third_party/polymer/v1_0/components-chromium/iron-icon/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-icon/.bower.json
index 6b09dea9..75ac273 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-icon/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-icon/.bower.json
@@ -1,7 +1,7 @@
 {
   "name": "iron-icon",
   "private": true,
-  "version": "1.0.5",
+  "version": "1.0.7",
   "license": "http://polymer.github.io/LICENSE.txt",
   "description": "An element that supports displaying an icon",
   "main": "iron-icon.html",
@@ -32,11 +32,11 @@
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
   "homepage": "https://github.com/PolymerElements/iron-icon",
-  "_release": "1.0.5",
+  "_release": "1.0.7",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.5",
-    "commit": "5217361e21016b3ca52b7bbf5ba2ad56b3301486"
+    "tag": "v1.0.7",
+    "commit": "6f4d152dc3998a6cc12a5a585a654f893dc99381"
   },
   "_source": "git://github.com/PolymerElements/iron-icon.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-icon/bower.json b/third_party/polymer/v1_0/components-chromium/iron-icon/bower.json
index 3a4206f..6693f96 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-icon/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-icon/bower.json
@@ -1,7 +1,7 @@
 {
   "name": "iron-icon",
   "private": true,
-  "version": "1.0.5",
+  "version": "1.0.7",
   "license": "http://polymer.github.io/LICENSE.txt",
   "description": "An element that supports displaying an icon",
   "main": "iron-icon.html",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-icon/iron-icon.html b/third_party/polymer/v1_0/components-chromium/iron-icon/iron-icon.html
index cbcb47d..5101f82f 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-icon/iron-icon.html
+++ b/third_party/polymer/v1_0/components-chromium/iron-icon/iron-icon.html
@@ -50,10 +50,11 @@
 
     <iron-icon icon="fruit:cherry"></iron-icon>
 
-See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for more information about
+See [iron-iconset](iron-iconset) and [iron-iconset-svg](iron-iconset-svg) for more information about
 how to create a custom iconset.
 
-See [iron-icons](https://elements.polymer-project.org/elements/iron-icons?view=demo:demo/index.html) for the default set of icons.
+See the [iron-icons demo](iron-icons?view=demo:demo/index.html) to see the icons available
+in the various iconsets.
 
 
 ### Styling
@@ -64,6 +65,8 @@
 ----------------|-------------|----------
 `--iron-icon-width` | Width of the icon | `24px`
 `--iron-icon-height` | Height of the icon | `24px`
+`--iron-icon-fill-color` | Fill color of the svg icon | `currentcolor`
+`--iron-icon-stroke-color` | Stroke color of the svg icon | none
 
 @group Iron Elements
 @element iron-icon
@@ -82,7 +85,8 @@
 
       vertical-align: middle;
 
-      fill: currentcolor;
+      fill: var(--iron-icon-fill-color, currentcolor);
+      stroke: var(--iron-icon-stroke-color, none);
 
       width: var(--iron-icon-width, 24px);
       height: var(--iron-icon-height, 24px);
diff --git a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/.bower.json
index 2a380920..37c716fe 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/.bower.json
@@ -1,7 +1,7 @@
 {
   "name": "iron-iconset-svg",
   "description": "Manages a set of svg icons",
-  "version": "1.0.6",
+  "version": "1.0.9",
   "keywords": [
     "web-components",
     "polymer",
@@ -29,12 +29,13 @@
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
     "web-component-tester": "*"
   },
+  "main": "iron-iconset-svg.html",
   "homepage": "https://github.com/PolymerElements/iron-iconset-svg",
-  "_release": "1.0.6",
+  "_release": "1.0.9",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.6",
-    "commit": "ebd17924942abe6110aa0fe81b1b31e1fcc34a9f"
+    "tag": "v1.0.9",
+    "commit": "ce9b2ea1f73d936cffdd05f3fe34b1f69d1d32db"
   },
   "_source": "git://github.com/PolymerElements/iron-iconset-svg.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/.travis.yml b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/.travis.yml
new file mode 100644
index 0000000..d4e78c4
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: UR1rxThVZH+l6fFHhAlgNIWs9wHmC5A102oAQBtCuQqKiXPZCDAPQHdjufX8z6hH93JkR+Esh2VPv0baSXFrHteKTRN6bsNDTMFDdHJ5BiRAdhVoV6bsdNH2GTgRXQ+ACMgrh4sXLA5+2Z+JGq7m0zaHehDfNZqmo/1U59qImP8=
+  - secure: PmWDypBdjKlUGPn9UoBEkjoYiyJFQGe2QiACmdOgueOLSLeA6xW+/1521uFIBHpwuWn29mxVYv5gS1D8hafWhZdXn4OYQl550RrT092jXIO6+mMKZXPmUaKCkPMY6QYJJ5j9ZOC36KgF//IpoE7OCxpLReYOD2KBR3mhw0jOYJA=
diff --git a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/README.md b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/README.md
index 10e8e26..f5b7e56 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/README.md
+++ b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/README.md
@@ -1,4 +1,50 @@
-iron-iconset-svg
-=========
 
-See the [component page](https://elements.polymer-project.org/elements/iron-iconset-svg) for more information.
+<!---
+
+This README is automatically generated from the comments in these files:
+iron-iconset-svg.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/iron-iconset-svg.svg?branch=master)](https://travis-ci.org/PolymerElements/iron-iconset-svg)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/iron-iconset-svg)_
+
+
+##&lt;iron-iconset-svg&gt;
+
+
+The `iron-iconset-svg` element allows users to define their own icon sets
+that contain svg icons. The svg icon elements should be children of the
+`iron-iconset-svg` element. Multiple icons should be given distinct id's.
+
+Using svg elements to create icons has a few advantages over traditional
+bitmap graphics like jpg or png. Icons that use svg are vector based so
+they are resolution independent and should look good on any device. They
+are stylable via css. Icons can be themed, colorized, and even animated.
+
+Example:
+
+    <iron-iconset-svg name="my-svg-icons" size="24">
+      <svg>
+        <defs>
+          <g id="shape">
+            <rect x="50" y="50" width="50" height="50" />
+            <circle cx="50" cy="50" r="50" />
+          </g>
+        </defs>
+      </svg>
+    </iron-iconset-svg>
+
+This will automatically register the icon set "my-svg-icons" to the iconset
+database.  To use these icons from within another element, make a
+`iron-iconset` element and call the `byId` method
+to retrieve a given iconset. To apply a particular icon inside an
+element use the `applyIcon` method. For example:
+
+    iconset.applyIcon(iconNode, 'car');
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/bower.json b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/bower.json
index 843d9bd..8467a3b 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/bower.json
@@ -1,7 +1,7 @@
 {
   "name": "iron-iconset-svg",
   "description": "Manages a set of svg icons",
-  "version": "1.0.6",
+  "version": "1.0.9",
   "keywords": [
     "web-components",
     "polymer",
@@ -28,5 +28,6 @@
     "test-fixture": "polymerelements/test-fixture#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
     "web-component-tester": "*"
-  }
+  },
+  "main": "iron-iconset-svg.html"
 }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/iron-iconset-svg-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/iron-iconset-svg-extracted.js
index 4bca3cc..f1e7cb92 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/iron-iconset-svg-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-iconset-svg/iron-iconset-svg-extracted.js
@@ -4,9 +4,9 @@
    * `iron-iconset-svg` element. Multiple icons should be given distinct id's.
    *
    * Using svg elements to create icons has a few advantages over traditional
-   * bitmap graphics like jpg or png. Icons that use svg are vector based so they
-   * are resolution independent and should look good on any device. They are
-   * stylable via css. Icons can be themed, colorized, and even animated.
+   * bitmap graphics like jpg or png. Icons that use svg are vector based so
+   * they are resolution independent and should look good on any device. They
+   * are stylable via css. Icons can be themed, colorized, and even animated.
    *
    * Example:
    *
@@ -14,8 +14,8 @@
    *       <svg>
    *         <defs>
    *           <g id="shape">
-   *             <rect x="50" y="50" width="50" height="50" />
-   *             <circle cx="50" cy="50" r="50" />
+   *             <rect x="12" y="0" width="12" height="24" />
+   *             <circle cx="12" cy="12" r="12" />
    *           </g>
    *         </defs>
    *       </svg>
@@ -31,18 +31,15 @@
    *
    * @element iron-iconset-svg
    * @demo demo/index.html
+   * @implements {Polymer.Iconset}
    */
   Polymer({
-
     is: 'iron-iconset-svg',
 
     properties: {
 
       /**
        * The name of the iconset.
-       *
-       * @attribute name
-       * @type string
        */
       name: {
         type: String,
@@ -51,10 +48,6 @@
 
       /**
        * The size of an individual icon. Note that icons must be square.
-       *
-       * @attribute iconSize
-       * @type number
-       * @default 24
        */
       size: {
         type: Number,
@@ -63,6 +56,10 @@
 
     },
 
+    attached: function() {
+      this.style.display = 'none';
+    },
+
     /**
      * Construct an array of all icon names in this iconset.
      *
@@ -84,7 +81,7 @@
      * @method applyIcon
      * @param {Element} element Element to which the icon is applied.
      * @param {string} iconName Name of the icon to apply.
-     * @return {Element} The svg element which renders the icon.
+     * @return {?Element} The svg element which renders the icon.
      */
     applyIcon: function(element, iconName) {
       // insert svg element into shadow root, if it exists
diff --git a/third_party/polymer/v1_0/components-chromium/iron-list/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-list/.bower.json
index d2a64e7e4..c5159e5 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-list/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-list/.bower.json
@@ -7,7 +7,7 @@
     "list",
     "virtual-list"
   ],
-  "version": "1.1.4",
+  "version": "1.1.5",
   "homepage": "https://github.com/PolymerElements/iron-list",
   "authors": [
     "The Polymer Authors"
@@ -37,11 +37,11 @@
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.2",
     "web-component-tester": "*"
   },
-  "_release": "1.1.4",
+  "_release": "1.1.5",
   "_resolution": {
     "type": "version",
-    "tag": "v1.1.4",
-    "commit": "7f1b6c05d96c2655ad138e99f3ee44d074f8df7b"
+    "tag": "v1.1.5",
+    "commit": "c6bf7caf1745cc3bed0769d41ac405476ef981b8"
   },
   "_source": "git://github.com/PolymerElements/iron-list.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-list/bower.json b/third_party/polymer/v1_0/components-chromium/iron-list/bower.json
index 772ab59a..3684260 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-list/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-list/bower.json
@@ -7,7 +7,7 @@
     "list",
     "virtual-list"
   ],
-  "version": "1.1.4",
+  "version": "1.1.5",
   "homepage": "https://github.com/PolymerElements/iron-list",
   "authors": [
     "The Polymer Authors"
diff --git a/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
index 883a7ba..df280d5 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-list/iron-list-extracted.js
@@ -228,6 +228,13 @@
     },
 
     /**
+     * The bottom of the scroll.
+     */
+    get _scrollBottom() {
+      return this._scrollPosition + this._viewportSize;
+    },
+
+    /**
      * The n-th item rendered in the last physical item.
      */
     get _virtualEnd() {
@@ -382,19 +389,13 @@
      * items in the viewport and recycle tiles as needed.
      */
     _refresh: function() {
-      var SCROLL_DIRECTION_UP = -1;
-      var SCROLL_DIRECTION_DOWN = 1;
-      var SCROLL_DIRECTION_NONE = 0;
-
       // clamp the `scrollTop` value
       // IE 10|11 scrollTop may go above `_maxScrollTop`
       // iOS `scrollTop` may go below 0 and above `_maxScrollTop`
       var scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scroller.scrollTop));
-
-      var tileHeight, kth, recycledTileSet;
+      var tileHeight, tileTop, kth, recycledTileSet, scrollBottom;
       var ratio = this._ratio;
       var delta = scrollTop - this._scrollPosition;
-      var direction = SCROLL_DIRECTION_NONE;
       var recycledTiles = 0;
       var hiddenContentSize = this._hiddenContentSize;
       var currentRatio = ratio;
@@ -406,18 +407,19 @@
       // clear cached visible index
       this._firstVisibleIndexVal = null;
 
+      scrollBottom = this._scrollBottom;
+
       // random access
       if (Math.abs(delta) > this._physicalSize) {
         this._physicalTop += delta;
-        direction = SCROLL_DIRECTION_NONE;
         recycledTiles =  Math.round(delta / this._physicalAverage);
       }
       // scroll up
       else if (delta < 0) {
         var topSpace = scrollTop - this._physicalTop;
         var virtualStart = this._virtualStart;
+        var physicalBottom = this._physicalBottom;
 
-        direction = SCROLL_DIRECTION_UP;
         recycledTileSet = [];
 
         kth = this._physicalEnd;
@@ -430,12 +432,14 @@
             // recycle less physical items than the total
             recycledTiles < this._physicalCount &&
             // ensure that these recycled tiles are needed
-            virtualStart - recycledTiles > 0
+            virtualStart - recycledTiles > 0 &&
+            // ensure that the tile is not visible
+            physicalBottom - this._physicalSizes[kth] > scrollBottom
         ) {
 
-          tileHeight = this._physicalSizes[kth] || this._physicalAverage;
+          tileHeight = this._physicalSizes[kth];
           currentRatio += tileHeight / hiddenContentSize;
-
+          physicalBottom -= tileHeight;
           recycledTileSet.push(kth);
           recycledTiles++;
           kth = (kth === 0) ? this._physicalCount - 1 : kth - 1;
@@ -443,15 +447,13 @@
 
         movingUp = recycledTileSet;
         recycledTiles = -recycledTiles;
-
       }
       // scroll down
       else if (delta > 0) {
-        var bottomSpace = this._physicalBottom - (scrollTop + this._viewportSize);
+        var bottomSpace = this._physicalBottom - scrollBottom;
         var virtualEnd = this._virtualEnd;
         var lastVirtualItemIndex = this._virtualCount-1;
 
-        direction = SCROLL_DIRECTION_DOWN;
         recycledTileSet = [];
 
         kth = this._physicalStart;
@@ -464,10 +466,12 @@
             // recycle less physical items than the total
             recycledTiles < this._physicalCount &&
             // ensure that these recycled tiles are needed
-            virtualEnd + recycledTiles < lastVirtualItemIndex
+            virtualEnd + recycledTiles < lastVirtualItemIndex &&
+            // ensure that the tile is not visible
+            this._physicalTop + this._physicalSizes[kth] < scrollTop
           ) {
 
-          tileHeight = this._physicalSizes[kth] || this._physicalAverage;
+          tileHeight = this._physicalSizes[kth];
           currentRatio += tileHeight / hiddenContentSize;
 
           this._physicalTop += tileHeight;
@@ -477,7 +481,15 @@
         }
       }
 
-      if (recycledTiles !== 0) {
+      if (recycledTiles === 0) {
+        // If the list ever reach this case, the physical average is not significant enough
+        // to create all the items needed to cover the entire viewport.
+        // e.g. A few items have a height that differs from the average by serveral order of magnitude.
+        if (this._increasePoolIfNeeded()) {
+          // yield and set models to the new items
+          this.async(this._update);
+        }
+      } else {
         this._virtualStart = this._virtualStart + recycledTiles;
         this._update(recycledTileSet, movingUp);
       }
@@ -509,7 +521,7 @@
 
       // increase the pool of physical items if needed
       if (this._increasePoolIfNeeded()) {
-        // set models to the new items
+        // yield set models to the new items
         this.async(this._update);
       }
     },
@@ -535,7 +547,7 @@
     },
 
     /**
-     * Increases the pool size. That is, the physical items in the DOM.
+     * Increases the pool of physical items only if needed.
      * This function will allocate additional physical items
      * (limited by `MAX_PHYSICAL_COUNT`) if the content size is shorter than
      * `_optPhysicalSize`
@@ -543,16 +555,22 @@
      * @return boolean
      */
     _increasePoolIfNeeded: function() {
-      if (this._physicalSize >= this._optPhysicalSize || this._physicalAverage === 0) {
+      if (this._physicalAverage === 0) {
         return false;
       }
+      if (this._physicalBottom < this._scrollBottom || this._physicalTop > this._scrollPosition) {
+        return this._increasePool(1);
+      }
+      if (this._physicalSize < this._optPhysicalSize) {
+        return this._increasePool(Math.round((this._optPhysicalSize - this._physicalSize) * 1.2 / this._physicalAverage));
+      }
+      return false;
+    },
 
-      // the estimated number of physical items that we will need to reach
-      // the cap established by `_optPhysicalSize`.
-      var missingItems = Math.round(
-          (this._optPhysicalSize - this._physicalSize) * 1.2 / this._physicalAverage
-        );
-
+    /**
+     * Increases the pool size.
+     */
+    _increasePool: function(missingItems) {
       // limit the size
       var nextPhysicalCount = Math.min(
           this._physicalCount + missingItems,
@@ -567,11 +585,8 @@
         return false;
       }
 
-      var newPhysicalItems = this._createPool(delta);
-      var emptyArray = new Array(delta);
-
-      [].push.apply(this._physicalItems, newPhysicalItems);
-      [].push.apply(this._physicalSizes, emptyArray);
+      [].push.apply(this._physicalItems, this._createPool(delta));
+      [].push.apply(this._physicalSizes, new Array(delta));
 
       this._physicalCount = prevPhysicalCount + delta;
 
@@ -966,10 +981,9 @@
 
       // increase the pool of physical items if needed
       if (this._increasePoolIfNeeded()) {
-        // set models to the new items
+        // yield set models to the new items
         this.async(this._update);
       }
-
       // clear cached visible index
       this._firstVisibleIndexVal = null;
     },
diff --git a/third_party/polymer/v1_0/components-chromium/iron-media-query/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-media-query/.bower.json
index 4441523..3cd0a8b 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-media-query/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-media-query/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-media-query",
-  "version": "1.0.3",
+  "version": "1.0.6",
   "description": "Lets you bind to a CSS media query",
   "authors": [
     "The Polymer Authors"
@@ -28,11 +28,12 @@
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.3",
+  "main": "iron-media-query.html",
+  "_release": "1.0.6",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.3",
-    "commit": "80e921f58e7688a840a0cf29e9e2aaaee72a66b2"
+    "tag": "v1.0.6",
+    "commit": "fda20cb8e3bb2b49c2473b8a41fd2afae51db468"
   },
   "_source": "git://github.com/PolymerElements/iron-media-query.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-media-query/.travis.yml b/third_party/polymer/v1_0/components-chromium/iron-media-query/.travis.yml
new file mode 100644
index 0000000..709938d
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-media-query/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: My9uxlkp4fZwSHKqo1RUv4yBhNl46XfbaiOsOStqJdI9l7hBfudSl7V2OZeLuV2pEDJC1z1ZqVU6C/K0/iTf7i66cd9g0iH5N+1qex8p2AcuP1evPWbwLw8moHH+M5E14MMXD8sPX4KauS8azmgRm61pppD5ZgKfCaeGZg7Tczs=
+  - secure: LgnZP4BNGBkTZhf8Vr7r9LdrOwq2/58TqqYkFFloEGBRT6HmumNSRwNbIwOh1U9jSTVkqjC2rn4G27u4XlEIs+QTD2PVSSEKy7Vbn0KxSNCvCGaOB1ZaxWTwZa7nkg09ZFRCHGh+WIbuV+BxyzsjOqlN82GSzFNSb3rxhqDM6dU=
diff --git a/third_party/polymer/v1_0/components-chromium/iron-media-query/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/iron-media-query/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-media-query/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/iron-media-query/README.md b/third_party/polymer/v1_0/components-chromium/iron-media-query/README.md
index f577b3c..a2c553d 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-media-query/README.md
+++ b/third_party/polymer/v1_0/components-chromium/iron-media-query/README.md
@@ -1,11 +1,28 @@
-# iron-media-query
+
+<!---
+
+This README is automatically generated from the comments in these files:
+iron-media-query.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/iron-media-query.svg?branch=master)](https://travis-ci.org/PolymerElements/iron-media-query)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/iron-media-query)_
+
+
+##&lt;iron-media-query&gt;
+
 
 `iron-media-query` can be used to data bind to a CSS media query.
 The `query` property is a bare CSS media query.
-The `query-matches` property is a boolean representing if the page matches that media query.
+The `query-matches` property is a boolean representing whether the page matches that media query.
 
 Example:
 
-```html
-<iron-media-query query="(min-width: 600px)" query-matches="{{queryMatches}}"></iron-media-query>
-```
+    <iron-media-query query="(min-width: 600px)" query-matches="{{queryMatches}}"></iron-media-query>
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/iron-media-query/bower.json b/third_party/polymer/v1_0/components-chromium/iron-media-query/bower.json
index 67670a1d..044bf5f 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-media-query/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-media-query/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-media-query",
-  "version": "1.0.3",
+  "version": "1.0.6",
   "description": "Lets you bind to a CSS media query",
   "authors": [
     "The Polymer Authors"
@@ -27,5 +27,6 @@
     "test-fixture": "PolymerElements/test-fixture#^1.0.0",
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
-  }
+  },
+  "main": "iron-media-query.html"
 }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-media-query/iron-media-query-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-media-query/iron-media-query-extracted.js
index 029d3bab..bfcd9a6 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-media-query/iron-media-query-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-media-query/iron-media-query-extracted.js
@@ -22,10 +22,29 @@
         observer: 'queryChanged'
       },
 
+      /**
+       * If true, the query attribute is assumed to be a complete media query
+       * string rather than a single media feature.
+       */
+      full: {
+        type: Boolean,
+        value: false
+      },
+      
+      /**
+       * @type {function(MediaQueryList)}
+       */ 
       _boundMQHandler: {
         value: function() {
           return this.queryHandler.bind(this);
         }
+      },
+      
+      /**
+       * @type {MediaQueryList}
+       */ 
+      _mq: {
+        value: null
       }
     },
 
@@ -56,7 +75,7 @@
       if (!query) {
         return;
       }
-      if (query[0] !== '(') {
+      if (!this.full && query[0] !== '(') {
         query = '(' + query + ')';
       }
       this._mq = window.matchMedia(query);
diff --git a/third_party/polymer/v1_0/components-chromium/iron-meta/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-meta/.bower.json
index 9e65079..e1304d17 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-meta/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-meta/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-meta",
-  "version": "1.0.3",
+  "version": "1.1.1",
   "keywords": [
     "web-components",
     "polymer"
@@ -25,12 +25,13 @@
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
+  "main": "iron-meta.html",
   "homepage": "https://github.com/PolymerElements/iron-meta",
-  "_release": "1.0.3",
+  "_release": "1.1.1",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.3",
-    "commit": "91529259262b0d8f33fed44bc3fd47aedf35cb04"
+    "tag": "v1.1.1",
+    "commit": "e171ee234b482219c9514e6f9551df48ef48bd9f"
   },
   "_source": "git://github.com/PolymerElements/iron-meta.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-meta/.travis.yml b/third_party/polymer/v1_0/components-chromium/iron-meta/.travis.yml
new file mode 100644
index 0000000..fd27446b
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-meta/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: eGcuDAJt+1GPrC6u95vHufjnSXWbVBZpW7oKQhZjcHrN19l9COdOb7RVkTPsZzEanHaH/D6Psr4WJKyd72Wx5wj+bqGh4nPHTFSnK3+gNT4eJAgLvsxLwHxW8QkYYHEdZe8Wd6sOdal9geeLZ8fG9xELYEtuJR6lww5uLvFv/cw=
+  - secure: DoBz8LDaS4/lQ9sTXE5pnp8fqEvG47mmdQaQ14EnHQ+wLbajIaLk59vRfau5c7mIef8dEgaT40r/kVP5QRr3OiH5UJY3jLnCMVIxWJ3ZTkuGGuU6QDQvoGSSBhdA+b+G94bbK6LtHQxRBrkiyT9d0IzT5ZiHlDlteGbjdDWAgw0=
diff --git a/third_party/polymer/v1_0/components-chromium/iron-meta/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/iron-meta/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-meta/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/iron-meta/README.md b/third_party/polymer/v1_0/components-chromium/iron-meta/README.md
index 26e2ddf..615c85b 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-meta/README.md
+++ b/third_party/polymer/v1_0/components-chromium/iron-meta/README.md
@@ -1,5 +1,21 @@
-iron-meta
-=========
+
+<!---
+
+This README is automatically generated from the comments in these files:
+iron-meta.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/iron-meta.svg?branch=master)](https://travis-ci.org/PolymerElements/iron-meta)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/iron-meta)_
+
+
+##&lt;iron-meta&gt;
+
 
 `iron-meta` is a generic element you can use for sharing information across the DOM tree.
 It uses [monostate pattern](http://c2.com/cgi/wiki?MonostatePattern) such that any
@@ -15,9 +31,7 @@
 
 If I create an instance like this:
 
-```html
-<iron-meta key="info" value="foo/bar"></iron-meta>
-```
+    <iron-meta key="info" value="foo/bar"></iron-meta>
 
 Note that value="foo/bar" is the metadata I've defined. I could define more
 attributes or use child nodes to define additional metadata.
@@ -25,22 +39,55 @@
 Now I can access that element (and it's metadata) from any iron-meta instance
 via the byKey method, e.g.
 
-```javascript
-meta.byKey('info').getAttribute('value');
-```
+    meta.byKey('info').getAttribute('value');
 
 Pure imperative form would be like:
 
-```javascript
-document.createElement('iron-meta').byKey('info').getAttribute('value');
-```
+    document.createElement('iron-meta').byKey('info').getAttribute('value');
 
 Or, in a Polymer element, you can include a meta in your template:
 
-```html
-<iron-meta id="meta"></iron-meta>
-```
+    <iron-meta id="meta"></iron-meta>
+    ...
+    this.$.meta.byKey('info').getAttribute('value');
 
-```javascript
-this.$.meta.byKey('info').getAttribute('value');
-```
+
+
+##&lt;iron-meta-query&gt;
+
+
+`iron-meta` is a generic element you can use for sharing information across the DOM tree.
+It uses [monostate pattern](http://c2.com/cgi/wiki?MonostatePattern) such that any
+instance of iron-meta has access to the shared
+information. You can use `iron-meta` to share whatever you want (or create an extension
+[like x-meta] for enhancements).
+
+The `iron-meta` instances containing your actual data can be loaded in an import,
+or constructed in any way you see fit. The only requirement is that you create them
+before you try to access them.
+
+Examples:
+
+If I create an instance like this:
+
+    <iron-meta key="info" value="foo/bar"></iron-meta>
+
+Note that value="foo/bar" is the metadata I've defined. I could define more
+attributes or use child nodes to define additional metadata.
+
+Now I can access that element (and it's metadata) from any iron-meta instance
+via the byKey method, e.g.
+
+    meta.byKey('info').getAttribute('value');
+
+Pure imperative form would be like:
+
+    document.createElement('iron-meta').byKey('info').getAttribute('value');
+
+Or, in a Polymer element, you can include a meta in your template:
+
+    <iron-meta id="meta"></iron-meta>
+    ...
+    this.$.meta.byKey('info').getAttribute('value');
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/iron-meta/bower.json b/third_party/polymer/v1_0/components-chromium/iron-meta/bower.json
index 65a1f8f4..614c5b3 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-meta/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-meta/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-meta",
-  "version": "1.0.3",
+  "version": "1.1.1",
   "keywords": [
     "web-components",
     "polymer"
@@ -24,5 +24,6 @@
     "test-fixture": "polymerelements/test-fixture#^1.0.0",
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
-  }
+  },
+  "main": "iron-meta.html"
 }
diff --git a/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js
index ea818120..df8ba0c 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta-extracted.js
@@ -3,6 +3,7 @@
     // monostate data
     var metaDatas = {};
     var metaArrays = {};
+    var singleton = null;
 
     Polymer.IronMeta = Polymer({
 
@@ -55,9 +56,15 @@
 
       },
 
+      hostAttributes: {
+        hidden: true
+      },
+
       /**
        * Only runs if someone invokes the factory/constructor directly
        * e.g. `new Polymer.IronMeta()`
+       *
+       * @param {{type: (string|undefined), key: (string|undefined), value}=} config
        */
       factoryImpl: function(config) {
         if (config) {
@@ -149,6 +156,13 @@
 
     });
 
+    Polymer.IronMeta.getIronMeta = function getIronMeta() {
+       if (singleton === null) {
+         singleton = new Polymer.IronMeta();
+       }
+       return singleton;
+     };
+
     /**
     `iron-meta-query` can be used to access infomation stored in `iron-meta`.
 
@@ -215,6 +229,8 @@
       /**
        * Actually a factory method, not a true constructor. Only runs if
        * someone invokes it directly (via `new Polymer.IronMeta()`);
+       *
+       * @param {{type: (string|undefined), key: (string|undefined)}=} config
        */
       factoryImpl: function(config) {
         if (config) {
diff --git a/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta.html b/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta.html
index e6e151e..1622a6a5 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta.html
+++ b/third_party/polymer/v1_0/components-chromium/iron-meta/iron-meta.html
@@ -31,7 +31,7 @@
 Now I can access that element (and it's metadata) from any iron-meta instance
 via the byKey method, e.g.
 
-    meta.byKey('info').getAttribute('value').
+    meta.byKey('info').getAttribute('value');
 
 Pure imperative form would be like:
 
diff --git a/third_party/polymer/v1_0/components-chromium/iron-range-behavior/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-range-behavior/.bower.json
index ea235a23..cb6b1b3 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-range-behavior/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-range-behavior/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-range-behavior",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "license": "http://polymer.github.io/LICENSE.txt",
   "description": "Provides a behavior for something with a minimum and maximum value",
   "authors": "The Polymer Authors",
@@ -28,11 +28,11 @@
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
   "homepage": "https://github.com/PolymerElements/iron-range-behavior",
-  "_release": "1.0.3",
+  "_release": "1.0.4",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.3",
-    "commit": "3ed9a372778e31e62477666b313155c581a7dfe6"
+    "tag": "v1.0.4",
+    "commit": "71774a7d8a8c377496bfe05e60b754e91216e0b9"
   },
   "_source": "git://github.com/PolymerElements/iron-range-behavior.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-range-behavior/bower.json b/third_party/polymer/v1_0/components-chromium/iron-range-behavior/bower.json
index 4dafd89..b4967a7 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-range-behavior/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-range-behavior/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-range-behavior",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "license": "http://polymer.github.io/LICENSE.txt",
   "description": "Provides a behavior for something with a minimum and maximum value",
   "authors": "The Polymer Authors",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-range-behavior/iron-range-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-range-behavior/iron-range-behavior-extracted.js
index cf4c54a..1db5ff6 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-range-behavior/iron-range-behavior-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-range-behavior/iron-range-behavior-extracted.js
@@ -1,8 +1,8 @@
-/** 
+/**
  * `iron-range-behavior` provides the behavior for something with a minimum to maximum range.
  *
  * @demo demo/index.html
- * @polymerBehavior 
+ * @polymerBehavior
  */
  Polymer.IronRangeBehavior = {
 
@@ -71,7 +71,7 @@
   _calcStep: function(value) {
    /**
     * if we calculate the step using
-    * `Math.round(value / step) * step` we may hit a precision point issue 
+    * `Math.round(value / step) * step` we may hit a precision point issue
     * eg. 0.1 * 0.2 =  0.020000000000000004
     * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
     *
@@ -79,7 +79,8 @@
     */
     // polymer/issues/2493
     value = parseFloat(value);
-    return this.step ? (Math.round((value + this.min) / this.step) / (1 / this.step)) - this.min : value;
+    return this.step ? (Math.round((value + this.min) / this.step) -
+        (this.min / this.step)) / (1 / this.step) : value;
   },
 
   _validateValue: function() {
diff --git a/third_party/polymer/v1_0/components-chromium/iron-selector/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-selector/.bower.json
index 8c65ba5e..52d44c1 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-selector/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-selector/.bower.json
@@ -1,12 +1,10 @@
 {
   "name": "iron-selector",
-  "version": "1.0.7",
+  "version": "1.0.8",
   "description": "Manages a set of elements that can be selected",
   "private": true,
   "license": "http://polymer.github.io/LICENSE.txt",
-  "main": [
-    "iron-selector.html"
-  ],
+  "main": "iron-selector.html",
   "authors": [
     "The Polymer Authors"
   ],
@@ -22,7 +20,7 @@
   "homepage": "https://github.com/PolymerElements/iron-selector",
   "ignore": [],
   "dependencies": {
-    "polymer": "Polymer/polymer#^1.0.0"
+    "polymer": "Polymer/polymer#^1.2.0"
   },
   "devDependencies": {
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
@@ -32,11 +30,11 @@
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.7",
+  "_release": "1.0.8",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.7",
-    "commit": "0b2f484ac3b1b03400da2d38b0f543f3688150a4"
+    "tag": "v1.0.8",
+    "commit": "e9a66727f3da0446f04956d4e4f1dcd51cdec2ff"
   },
   "_source": "git://github.com/PolymerElements/iron-selector.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-selector/.travis.yml b/third_party/polymer/v1_0/components-chromium/iron-selector/.travis.yml
new file mode 100644
index 0000000..eca93211
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/iron-selector/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: ltCkwJM0nkTS9WjikyjqBsB5J2hQon4UnVVrINk4y+Vq4v9PQJH3+83nya0jnxilKaeAJs4d2/OS02F9GkqYpsSmDz7OgXPfk0hrHA8UksvvpSALfnukleIAN2YTOcxXJKeNHcfpqCKPk1dGeNQOEM61H+QgTBIyFB3sMugygqs=
+  - secure: TJuu1WdpFLTaBN/prBafm8Pld/BQCySNuuG1nATbF3fqiOpgehXu8Z5URAz5syUhqZAyEmuRMxvXpEVD/t1jrtaXVwkdCFkkQ4ckkP4gTIeSGA/Puw8sveB2q7QAqXyTmeFkocNlh8fxV+B07o0SPWdhcvdZnDVU9VrpSqL+92M=
diff --git a/third_party/polymer/v1_0/components-chromium/iron-selector/bower.json b/third_party/polymer/v1_0/components-chromium/iron-selector/bower.json
index ff00842..a633301 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-selector/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-selector/bower.json
@@ -1,12 +1,10 @@
 {
   "name": "iron-selector",
-  "version": "1.0.7",
+  "version": "1.0.8",
   "description": "Manages a set of elements that can be selected",
   "private": true,
   "license": "http://polymer.github.io/LICENSE.txt",
-  "main": [
-    "iron-selector.html"
-  ],
+  "main": "iron-selector.html",
   "authors": [
     "The Polymer Authors"
   ],
@@ -22,7 +20,7 @@
   "homepage": "https://github.com/PolymerElements/iron-selector",
   "ignore": [],
   "dependencies": {
-    "polymer": "Polymer/polymer#^1.0.0"
+    "polymer": "Polymer/polymer#^1.2.0"
   },
   "devDependencies": {
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-selector/iron-multi-selectable-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-selector/iron-multi-selectable-extracted.js
index c1cc623..de4827b 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-selector/iron-multi-selectable-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-selector/iron-multi-selectable-extracted.js
@@ -58,6 +58,11 @@
       this._selection.multi = multi;
     },
 
+    get _shouldUpdateSelection() {
+      return this.selected != null ||
+        (this.selectedValues != null && this.selectedValues.length);
+    },
+
     _updateSelected: function() {
       if (this.multi) {
         this._selectMulti(this.selectedValues);
diff --git a/third_party/polymer/v1_0/components-chromium/iron-selector/iron-selectable-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-selector/iron-selectable-extracted.js
index 4afe648..f52a512 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-selector/iron-selectable-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-selector/iron-selectable-extracted.js
@@ -50,6 +50,8 @@
 
       /**
        * Returns the currently selected item.
+       *
+       * @type {?Object}
        */
       selectedItem: {
         type: Object,
@@ -91,10 +93,20 @@
       },
 
       /**
+       * The list of items from which a selection can be made.
+       */
+      items: {
+        type: Array,
+        readOnly: true,
+        value: function() {
+          return [];
+        }
+      },
+
+      /**
        * The set of excluded elements where the key is the `localName`
        * of the element that will be ignored from the item list.
        *
-       * @type {object}
        * @default {template: 1}
        */
       _excludedLocalNames: {
@@ -114,15 +126,12 @@
     created: function() {
       this._bindFilterItem = this._filterItem.bind(this);
       this._selection = new Polymer.IronSelection(this._applySelection.bind(this));
-      // TODO(cdata): When polymer/polymer#2535 lands, we do not need to do this
-      // book keeping anymore:
-      this.__listeningForActivate = false;
     },
 
     attached: function() {
       this._observer = this._observeItems(this);
-      this._contentObserver = this._observeContent(this);
-      if (!this.selectedItem && this.selected) {
+      this._updateItems();
+      if (!this._shouldUpdateSelection) {
         this._updateSelected(this.attrForSelected,this.selected)
       }
       this._addListener(this.activateEvent);
@@ -130,26 +139,12 @@
 
     detached: function() {
       if (this._observer) {
-        this._observer.disconnect();
-      }
-      if (this._contentObserver) {
-        this._contentObserver.disconnect();
+        Polymer.dom(this).unobserveNodes(this._observer);
       }
       this._removeListener(this.activateEvent);
     },
 
     /**
-     * Returns an array of selectable items.
-     *
-     * @property items
-     * @type Array
-     */
-    get items() {
-      var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
-      return Array.prototype.filter.call(nodes, this._bindFilterItem);
-    },
-
-    /**
      * Returns the index of the given item.
      *
      * @method indexOf
@@ -191,18 +186,16 @@
       this.selected = this._indexToValue(index);
     },
 
-    _addListener: function(eventName) {
-      if (!this.isAttached || this.__listeningForActivate) {
-        return;
-      }
+    get _shouldUpdateSelection() {
+      return this.selected != null;
+    },
 
-      this.__listeningForActivate = true;
+    _addListener: function(eventName) {
       this.listen(this, eventName, '_activateHandler');
     },
 
     _removeListener: function(eventName) {
       this.unlisten(this, eventName, '_activateHandler');
-      this.__listeningForActivate = false;
     },
 
     _activateEventChanged: function(eventName, old) {
@@ -210,6 +203,12 @@
       this._addListener(eventName);
     },
 
+    _updateItems: function() {
+      var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
+      nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
+      this._setItems(nodes);
+    },
+
     _updateSelected: function() {
       this._selectSelected(this.selected);
     },
@@ -268,18 +267,9 @@
       this._setSelectedItem(this._selection.get());
     },
 
-    // observe content changes under the given node.
-    _observeContent: function(node) {
-      var content = node.querySelector('content');
-      if (content && content.parentElement === node) {
-        return this._observeItems(node.domHost);
-      }
-    },
-
     // observe items change under the given node.
     _observeItems: function(node) {
-      // TODO(cdata): Update this when we get distributed children changed.
-      var observer = new MutationObserver(function(mutations) {
+      return Polymer.dom(node).observeNodes(function(mutations) {
         // Let other interested parties know about the change so that
         // we don't have to recreate mutation observers everywher.
         this.fire('iron-items-changed', mutations, {
@@ -287,15 +277,12 @@
           cancelable: false
         });
 
-        if (this.selected != null) {
+        this._updateItems();
+
+        if (this._shouldUpdateSelection) {
           this._updateSelected();
         }
-      }.bind(this));
-      observer.observe(node, {
-        childList: true,
-        subtree: true
       });
-      return observer;
     },
 
     _activateHandler: function(e) {
diff --git a/third_party/polymer/v1_0/components-chromium/iron-test-helpers/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-test-helpers/.bower.json
index 9af09c78..46c9cf5 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-test-helpers/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-test-helpers/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-test-helpers",
-  "version": "1.0.4",
+  "version": "1.0.6",
   "authors": [
     "The Polymer Authors"
   ],
@@ -25,11 +25,11 @@
   "devDependencies": {
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.4",
+  "_release": "1.0.6",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.4",
-    "commit": "d5d7124ca843ce3e5e73a90733f62a0cb1fac316"
+    "tag": "v1.0.6",
+    "commit": "940e5b8c5c7c878f51cf259019d3e3243f18d0b3"
   },
   "_source": "git://github.com/PolymerElements/iron-test-helpers.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-test-helpers/bower.json b/third_party/polymer/v1_0/components-chromium/iron-test-helpers/bower.json
index 7f21724..53e335fd 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-test-helpers/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-test-helpers/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-test-helpers",
-  "version": "1.0.4",
+  "version": "1.0.6",
   "authors": [
     "The Polymer Authors"
   ],
diff --git a/third_party/polymer/v1_0/components-chromium/iron-test-helpers/mock-interactions.js b/third_party/polymer/v1_0/components-chromium/iron-test-helpers/mock-interactions.js
index a21d3f0..52b52b1 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-test-helpers/mock-interactions.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-test-helpers/mock-interactions.js
@@ -143,7 +143,10 @@
   }
 
   function keyboardEventFor(type, keyCode) {
-    var event = new CustomEvent(type);
+    var event = new CustomEvent(type, {
+      bubbles: true,
+      cancelable: true
+    });
 
     event.keyCode = keyCode;
     event.code = keyCode;
diff --git a/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/.bower.json b/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/.bower.json
index d516617..62842a49 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-validatable-behavior",
-  "version": "1.0.4",
+  "version": "1.0.5",
   "description": "Provides a behavior for an element that validates user input",
   "authors": "The Polymer Authors",
   "keywords": [
@@ -32,11 +32,11 @@
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.4",
+  "_release": "1.0.5",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.4",
-    "commit": "ff267b561b032608755d705c1a7e346454b0aee4"
+    "tag": "v1.0.5",
+    "commit": "c1334b835892b3d7a329a8e6b8741d4be3a8d99c"
   },
   "_source": "git://github.com/PolymerElements/iron-validatable-behavior.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/bower.json b/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/bower.json
index 2dac6f94..f57fff7 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "iron-validatable-behavior",
-  "version": "1.0.4",
+  "version": "1.0.5",
   "description": "Provides a behavior for an element that validates user input",
   "authors": "The Polymer Authors",
   "keywords": [
diff --git a/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/iron-validatable-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/iron-validatable-behavior-extracted.js
index 33319ad9..0c82fad 100644
--- a/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/iron-validatable-behavior-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/iron-validatable-behavior/iron-validatable-behavior-extracted.js
@@ -1,5 +1,18 @@
 /**
-   * Use `Polymer.IronValidatableBehavior` to implement an element that validates user input.
+   * `Use Polymer.IronValidatableBehavior` to implement an element that validates user input.
+   * Use the related `Polymer.IronValidatorBehavior` to add custom validation logic to an iron-input.
+   *
+   * By default, an `<iron-form>` element validates its fields when the user presses the submit button.
+   * To validate a form imperatively, call the form's `validate()` method, which in turn will
+   * call `validate()` on all its children. By using `Polymer.IronValidatableBehavior`, your
+   * custom element will get a public `validate()`, which
+   * will return the validity of the element, and a corresponding `invalid` attribute,
+   * which can be used for styling.
+   *
+   * To implement the custom validation logic of your element, you must override
+   * the protected `_getValidity()` method of this behaviour, rather than `validate()`.
+   * See [this](https://github.com/PolymerElements/iron-form/blob/master/demo/simple-element.html)
+   * for an example.
    *
    * ### Accessibility
    *
diff --git a/third_party/polymer/v1_0/components-chromium/neon-animation/.bower.json b/third_party/polymer/v1_0/components-chromium/neon-animation/.bower.json
index 921a306a..fa31ad1 100644
--- a/third_party/polymer/v1_0/components-chromium/neon-animation/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/neon-animation/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "neon-animation",
-  "version": "1.0.7",
+  "version": "1.0.8",
   "authors": [
     "The Polymer Authors"
   ],
@@ -48,11 +48,11 @@
     "iron-icons": "PolymerElements/iron-icons#^1.0.0",
     "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0"
   },
-  "_release": "1.0.7",
+  "_release": "1.0.8",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.7",
-    "commit": "02daf22e000ed6afeecf6ae0291ae11e6eebbfcf"
+    "tag": "v1.0.8",
+    "commit": "36656916b75a4715b025a03473620002c2650ee8"
   },
   "_source": "git://github.com/PolymerElements/neon-animation.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/neon-animation/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/neon-animation/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/neon-animation/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/neon-animation/bower.json b/third_party/polymer/v1_0/components-chromium/neon-animation/bower.json
index cdbbb15..2e3d0c6 100644
--- a/third_party/polymer/v1_0/components-chromium/neon-animation/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/neon-animation/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "neon-animation",
-  "version": "1.0.7",
+  "version": "1.0.8",
   "authors": [
     "The Polymer Authors"
   ],
diff --git a/third_party/polymer/v1_0/components-chromium/neon-animation/neon-animatable-extracted.js b/third_party/polymer/v1_0/components-chromium/neon-animation/neon-animatable-extracted.js
index acab9f19..9d96aef 100644
--- a/third_party/polymer/v1_0/components-chromium/neon-animation/neon-animatable-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/neon-animation/neon-animatable-extracted.js
@@ -3,7 +3,8 @@
     is: 'neon-animatable',
 
     behaviors: [
-      Polymer.NeonAnimatableBehavior
+      Polymer.NeonAnimatableBehavior,
+      Polymer.IronResizableBehavior
     ]
 
   });
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-behaviors/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-behaviors/.bower.json
index d1ea3b2..3579b52 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-behaviors/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-behaviors/.bower.json
@@ -1,12 +1,13 @@
 {
   "name": "paper-behaviors",
-  "version": "1.0.7",
+  "version": "1.0.9",
   "description": "Common behaviors across the paper elements",
   "authors": [
     "The Polymer Authors"
   ],
   "main": [
     "paper-button-behavior.html",
+    "paper-checked-element-behavior.html",
     "paper-inky-focus-behavior.html"
   ],
   "keywords": [
@@ -37,11 +38,11 @@
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.7",
+  "_release": "1.0.9",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.7",
-    "commit": "7a674a3635fcb6db4842d16d3fd768ab07d638a8"
+    "tag": "v1.0.9",
+    "commit": "d9c0398cbaf3881bef3533b5b2b6127fc4d0960c"
   },
   "_source": "git://github.com/PolymerElements/paper-behaviors.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-behaviors/bower.json b/third_party/polymer/v1_0/components-chromium/paper-behaviors/bower.json
index 7ba2d20..8446398 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-behaviors/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-behaviors/bower.json
@@ -1,12 +1,13 @@
 {
   "name": "paper-behaviors",
-  "version": "1.0.7",
+  "version": "1.0.9",
   "description": "Common behaviors across the paper elements",
   "authors": [
     "The Polymer Authors"
   ],
   "main": [
     "paper-button-behavior.html",
+    "paper-checked-element-behavior.html",
     "paper-inky-focus-behavior.html"
   ],
   "keywords": [
diff --git a/third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js
index 6d8bc12d..86f699552 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-behaviors/paper-inky-focus-behavior-extracted.js
@@ -1,7 +1,7 @@
 /**
    * `Polymer.PaperInkyFocusBehavior` implements a ripple when the element has keyboard focus.
    *
-   * @polymerBehavior Polymer.PaperInkyFocusBehaviorImpl
+   * @polymerBehavior Polymer.PaperInkyFocusBehavior
    */
   Polymer.PaperInkyFocusBehaviorImpl = {
 
diff --git a/third_party/polymer/v1_0/components-chromium/paper-card/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-card/.bower.json
index 5bf7211..f037d0a 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-card/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-card/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-card",
-  "version": "1.0.6",
+  "version": "1.0.7",
   "description": "Material design piece of paper with unique related data",
   "authors": [
     "The Polymer Authors"
@@ -36,11 +36,11 @@
     "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
     "paper-styles": "PolymerElements/paper-styles#^1.0.0"
   },
-  "_release": "1.0.6",
+  "_release": "1.0.7",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.6",
-    "commit": "f2f4bf05e7b3746b39b9ad1d468d8031b236e2b6"
+    "tag": "v1.0.7",
+    "commit": "a1a0b2789b657a9b2bce17483ecc495ce968b104"
   },
   "_source": "git://github.com/PolymerElements/paper-card.git",
   "_target": "*",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-card/bower.json b/third_party/polymer/v1_0/components-chromium/paper-card/bower.json
index 00350b7..7e4b7ccc7 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-card/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-card/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-card",
-  "version": "1.0.6",
+  "version": "1.0.7",
   "description": "Material design piece of paper with unique related data",
   "authors": [
     "The Polymer Authors"
diff --git a/third_party/polymer/v1_0/components-chromium/paper-card/paper-card-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-card/paper-card-extracted.js
index 939077c..7b684d6 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-card/paper-card-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-card/paper-card-extracted.js
@@ -26,7 +26,8 @@
        */
       elevation: {
         type: Number,
-        value: 1
+        value: 1,
+        reflectToAttribute: true
       },
 
       /**
@@ -36,6 +37,17 @@
       animatedShadow: {
         type: Boolean,
         value: false
+      },
+
+      /**
+       * Read-only property used to pass down the `animatedShadow` value to
+       * the underlying paper-material style (since they have different names).
+       */
+      animated: {
+        type: Boolean,
+        reflectToAttribute: true,
+        readOnly: true,
+        computed: '_computeAnimated(animatedShadow)'
       }
     },
 
@@ -49,5 +61,9 @@
       if (image)
         cls += ' over-image';
       return cls;
+    },
+
+    _computeAnimated: function(animatedShadow) {
+      return animatedShadow;
     }
   });
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-card/paper-card.html b/third_party/polymer/v1_0/components-chromium/paper-card/paper-card.html
index a29cbfe..b1c09ac 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-card/paper-card.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-card/paper-card.html
@@ -11,7 +11,7 @@
 <link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
 
 <!--
-Material Design: <a href="http://www.google.com/design/spec/components/cards.html">Cards</a>
+Material design: [Cards](https://www.google.com/design/spec/components/cards.html)
 
 `paper-card` is a container with a drop shadow.
 
@@ -29,7 +29,7 @@
     <paper-card heading="Card Title" image="/path/to/image.png">
       ...
     </paper-card>
-    
+
 ### Accessibility
 
 By default, the `aria-label` will be set to the value of the `heading` attribute.
@@ -56,7 +56,7 @@
 
 </head><body><dom-module id="paper-card">
   <template>
-    <style>
+    <style include="paper-material">
       :host {
         display: inline-block;
         position: relative;
@@ -67,11 +67,6 @@
         @apply(--paper-card);
       }
 
-      paper-material {
-        border-radius: inherit;
-        @apply(--layout-fit);
-      }
-
       /* IE 10 support for HTML5 hidden attr */
       [hidden] {
         display: none !important;
@@ -79,6 +74,9 @@
 
       .header {
         position: relative;
+        border-top-left-radius: inherit;
+        border-top-right-radius: inherit;
+        overflow: hidden;
         @apply(--paper-card-header);
       }
 
@@ -116,8 +114,6 @@
       }
     </style>
 
-    <paper-material animated$="[[animatedShadow]]" elevation="[[elevation]]"></paper-material>
-
     <div class="header">
       <img hidden$="[[!image]]" src="[[image]]">
       <div hidden$="[[!heading]]" class$="[[_computeHeadingClass(image)]]">[[heading]]</div>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-checkbox/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-checkbox/.bower.json
index 937e0137..b253cdd 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-checkbox/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-checkbox/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-checkbox",
-  "version": "1.0.13",
+  "version": "1.0.14",
   "description": "A material design checkbox",
   "authors": [
     "The Polymer Authors"
@@ -35,11 +35,12 @@
     "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
     "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
   },
-  "_release": "1.0.13",
+  "main": "paper-checkbox.html",
+  "_release": "1.0.14",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.13",
-    "commit": "33f38432fb26fe5638ecce44fbe10a794f4bdff4"
+    "tag": "v1.0.14",
+    "commit": "be311b93234bbb15b527220ace17a30706657948"
   },
   "_source": "git://github.com/PolymerElements/paper-checkbox.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-checkbox/.travis.yml b/third_party/polymer/v1_0/components-chromium/paper-checkbox/.travis.yml
new file mode 100644
index 0000000..2eabb9e
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-checkbox/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: PkxMaBcKe8HD1Jv8O6qiyQ4Nux6DfaVyN/ss9opajX9Oqa2ECJRI/OCsjDSrgXKhuAc2dw0L/KwSb/j4hg3/9BzHlJYQmeR9b9+MsO377TseNw5aKlywgVRu2bj8ODv2naQ4pB4B/Us/n9K7J0vlHIwM8UAJJwGjYm2oYTQxCAw=
+  - secure: WQNRMEQEm6k5e+rzN08Lg0IBC83AZLz1QLP89z59JHLrAOeBu7CBh/LFG0OkhUnTC+dG2JdfIZbdQVCEciDyONjSIKzmM4ze9/LrGzFpROE8bU0ylYSLqX+3CK/6i7VMR3pJo79e1KOeprppHiJSRLVBJfhG+5uNgwAXws/sLQ4=
diff --git a/third_party/polymer/v1_0/components-chromium/paper-checkbox/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/paper-checkbox/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-checkbox/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/paper-checkbox/README.md b/third_party/polymer/v1_0/components-chromium/paper-checkbox/README.md
index 01eddc1a..a3abdfa 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-checkbox/README.md
+++ b/third_party/polymer/v1_0/components-chromium/paper-checkbox/README.md
@@ -1,4 +1,23 @@
-# paper-checkbox
+
+<!---
+
+This README is automatically generated from the comments in these files:
+metadata.html  paper-checkbox.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/paper-checkbox.svg?branch=master)](https://travis-ci.org/PolymerElements/paper-checkbox)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/paper-checkbox)_
+
+
+##&lt;paper-checkbox&gt;
+
+
+Material design: [Checkbox](https://www.google.com/design/spec/components/selection-controls.html#selection-controls-checkbox)
 
 `paper-checkbox` is a button that can be either checked or unchecked.  User
 can tap the checkbox to check or uncheck it.  Usually you use checkboxes
@@ -8,28 +27,24 @@
 
 Example:
 
-```html
-<paper-checkbox>label</paper-checkbox>
+    <paper-checkbox>label</paper-checkbox>
 
-<paper-checkbox checked>label</paper-checkbox>
-```
+    <paper-checkbox checked> label</paper-checkbox>
 
-Styling a checkbox:
+### Styling
 
-```html
-<style is="custom-style">
-  paper-checkbox {
-    --paper-checkbox-label-color: #000;
-    --paper-checkbox-checkmark-color: #fff;
+The following custom properties and mixins are available for styling:
 
-    /* Unhecked state colors. */
-    --paper-checkbox-unchecked-color: #5a5a5a;
-    --paper-checkbox-unchecked-background-color: #5a5a5a;
-    --paper-checkbox-unchecked-ink-color: #5a5a5a;
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-checkbox-unchecked-background-color` | Checkbox background color when the input is not checked | `transparent`
+`--paper-checkbox-unchecked-color` | Checkbox border color when the input is not checked | `--primary-text-color`
+`--paper-checkbox-unchecked-ink-color` | Selected/focus ripple color when the input is not checked | `--primary-text-color`
+`--paper-checkbox-checked-color` | Checkbox color when the input is checked | `--default-primary-color`
+`--paper-checkbox-checked-ink-color` | Selected/focus ripple color when the input is checked | `--default-primary-color`
+`--paper-checkbox-checkmark-color` | Checkmark color | `white`
+`--paper-checkbox-label-color` | Label color | `--primary-text-color`
+`--paper-checkbox-label-spacing` | Spacing between the label and the checkbox | `8px`
+`--paper-checkbox-error-color` | Checkbox color when invalid | `--google-red-500`
 
-    /* Checked state colors. */
-    --paper-checkbox-checked-color: #009688;
-    --paper-checkbox-checked-ink-color: #009688;
-  }
-</style>
-```
+
diff --git a/third_party/polymer/v1_0/components-chromium/paper-checkbox/bower.json b/third_party/polymer/v1_0/components-chromium/paper-checkbox/bower.json
index a02e71d..5e3598d 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-checkbox/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-checkbox/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-checkbox",
-  "version": "1.0.13",
+  "version": "1.0.14",
   "description": "A material design checkbox",
   "authors": [
     "The Polymer Authors"
@@ -34,5 +34,6 @@
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
     "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
     "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
-  }
+  },
+  "main": "paper-checkbox.html"
 }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-checkbox/paper-checkbox.html b/third_party/polymer/v1_0/components-chromium/paper-checkbox/paper-checkbox.html
index 8b4207d..ffaf078 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-checkbox/paper-checkbox.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-checkbox/paper-checkbox.html
@@ -52,6 +52,7 @@
       :host {
         display: inline-block;
         white-space: nowrap;
+        cursor: pointer;
       }
 
       :host(:focus) {
@@ -67,9 +68,6 @@
         position: relative;
         width: 18px;
         height: 18px;
-        cursor: pointer;
-        -webkit-transform: translateZ(0);
-        transform: translateZ(0);
         vertical-align: middle;
         background-color: var(--paper-checkbox-unchecked-background-color, transparent);
       }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/.bower.json
index e321eb38..a15ede3 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-drawer-panel",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "description": "A responsive drawer panel",
   "authors": [
     "The Polymer Authors"
@@ -19,22 +19,25 @@
   "license": "http://polymer.github.io/LICENSE.txt",
   "homepage": "https://github.com/PolymerElements/paper-drawer-panel",
   "dependencies": {
-    "polymer": "Polymer/polymer#^1.0.0",
+    "iron-media-query": "PolymerElements/iron-media-query#^1.0.0",
+    "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0",
     "iron-selector": "PolymerElements/iron-selector#^1.0.0",
-    "iron-media-query": "PolymerElements/iron-media-query#^1.0.0"
+    "polymer": "Polymer/polymer#^1.1.0"
   },
   "devDependencies": {
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
     "paper-button": "PolymerElements/paper-button#^1.0.0",
     "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.3",
+  "main": "paper-drawer-panel.html",
+  "_release": "1.0.4",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.3",
-    "commit": "92713b61eb8eec378db63af61b73341453b8180d"
+    "tag": "v1.0.4",
+    "commit": "9d4a4c737d8e2e5d23baee39128625e476f2b051"
   },
   "_source": "git://github.com/PolymerElements/paper-drawer-panel.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/README.md b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/README.md
index 2828663..80d67359 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/README.md
+++ b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/README.md
@@ -1,4 +1,21 @@
-# paper-drawer-panel
+
+<!---
+
+This README is automatically generated from the comments in these files:
+paper-drawer-panel.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/paper-drawer-panel)_
+
+
+##&lt;paper-drawer-panel&gt;
+
+
+Material design: [Navigation drawer](https://www.google.com/design/spec/patterns/navigation-drawer.html)
 
 `paper-drawer-panel` contains a drawer panel and a main panel.  The drawer
 and the main panel are side-by-side with drawer on the left.  When the browser
@@ -12,30 +29,26 @@
 
 Example:
 
-```html
-<paper-drawer-panel>
-  <div drawer> Drawer panel... </div>
-  <div main> Main panel... </div>
-</paper-drawer-panel>
-```
+    <paper-drawer-panel>
+      <div drawer> Drawer panel... </div>
+      <div main> Main panel... </div>
+    </paper-drawer-panel>
 
 The drawer and the main panels are not scrollable.  You can set CSS overflow
 property on the elements to make them scrollable or use `paper-header-panel`.
 
 Example:
 
-```html
-<paper-drawer-panel>
-  <paper-header-panel drawer>
-    <paper-toolbar></paper-toolbar>
-    <div> Drawer content... </div>
-  </paper-header-panel>
-  <paper-header-panel main>
-    <paper-toolbar></paper-toolbar>
-    <div> Main content... </div>
-  </paper-header-panel>
-</paper-drawer-panel>
-```
+    <paper-drawer-panel>
+      <paper-header-panel drawer>
+        <paper-toolbar></paper-toolbar>
+        <div> Drawer content... </div>
+      </paper-header-panel>
+      <paper-header-panel main>
+        <paper-toolbar></paper-toolbar>
+        <div> Main content... </div>
+      </paper-header-panel>
+    </paper-drawer-panel>
 
 An element that should toggle the drawer will automatically do so if it's
 given the `paper-drawer-toggle` attribute.  Also this element will automatically
@@ -43,29 +56,72 @@
 
 Example:
 
-```html
-<paper-drawer-panel>
-  <paper-header-panel drawer>
-    <paper-toolbar>
-      <div>Application</div>
-    </paper-toolbar>
-    <div> Drawer content... </div>
-  </paper-header-panel>
-  <paper-header-panel main>
-    <paper-toolbar>
-      <paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button>
-      <div>Title</div>
-    </paper-toolbar>
-    <div> Main content... </div>
-  </paper-header-panel>
-</paper-drawer-panel>
-```
+    <paper-drawer-panel>
+      <paper-header-panel drawer>
+        <paper-toolbar>
+          <div>Application</div>
+        </paper-toolbar>
+        <div> Drawer content... </div>
+      </paper-header-panel>
+      <paper-header-panel main>
+        <paper-toolbar>
+          <paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button>
+          <div>Title</div>
+        </paper-toolbar>
+        <div> Main content... </div>
+      </paper-header-panel>
+    </paper-drawer-panel>
 
 To position the drawer to the right, add `right-drawer` attribute.
 
-```html
-<paper-drawer-panel right-drawer>
-  <div drawer> Drawer panel... </div>
-  <div main> Main panel... </div>
-</paper-drawer-panel>
-```
+    <paper-drawer-panel right-drawer>
+      <div drawer> Drawer panel... </div>
+      <div main> Main panel... </div>
+    </paper-drawer-panel>
+
+### Styling
+
+To change the main container:
+
+    paper-drawer-panel {
+      --paper-drawer-panel-main-container: {
+        background-color: gray;
+      };
+    }
+
+To change the drawer container when it's in the left side:
+
+    paper-drawer-panel {
+      --paper-drawer-panel-left-drawer-container: {
+        background-color: white;
+      };
+    }
+
+To change the drawer container when it's in the right side:
+
+    paper-drawer-panel {
+      --paper-drawer-panel-right-drawer-container: {
+        background-color: white;
+      };
+    }
+
+To customize the scrim:
+
+    paper-drawer-panel {
+      --paper-drawer-panel-scrim: {
+        background-color: red;
+      };
+    }
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-drawer-panel-scrim-opacity` | Scrim opacity | 1
+`--paper-drawer-panel-drawer-container` | Mixin applied to drawer container | {}
+`--paper-drawer-panel-left-drawer-container` | Mixin applied to container when it's in the left side | {}
+`--paper-drawer-panel-main-container` | Mixin applied to main container | {}
+`--paper-drawer-panel-right-drawer-container` | Mixin applied to container when it's in the right side | {}
+`--paper-drawer-panel-scrim` | Mixin applied to scrim | {}
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/bower.json b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/bower.json
index 76a2f0c6..dbfded0 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-drawer-panel",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "description": "A responsive drawer panel",
   "authors": [
     "The Polymer Authors"
@@ -19,15 +19,18 @@
   "license": "http://polymer.github.io/LICENSE.txt",
   "homepage": "https://github.com/PolymerElements/paper-drawer-panel",
   "dependencies": {
-    "polymer": "Polymer/polymer#^1.0.0",
+    "iron-media-query": "PolymerElements/iron-media-query#^1.0.0",
+    "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0",
     "iron-selector": "PolymerElements/iron-selector#^1.0.0",
-    "iron-media-query": "PolymerElements/iron-media-query#^1.0.0"
+    "polymer": "Polymer/polymer#^1.1.0"
   },
   "devDependencies": {
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
     "paper-button": "PolymerElements/paper-button#^1.0.0",
     "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
-  }
+  },
+  "main": "paper-drawer-panel.html"
 }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js
index 11d31640..fff3afd 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js
@@ -1,453 +1,459 @@
 (function() {
+      'use strict';
 
-    'use strict';
+      // this would be the only `paper-drawer-panel` in
+      // the whole app that can be in `dragging` state
+      var sharedPanel = null;
 
-   // this would be the only `paper-drawer-panel` in
-   // the whole app that can be in `dragging` state
-    var sharedPanel = null;
-
-    function classNames(obj) {
-      var classes = [];
-      for (var key in obj) {
-        if (obj.hasOwnProperty(key) && obj[key]) {
-          classes.push(key);
+      function classNames(obj) {
+        var classes = [];
+        for (var key in obj) {
+          if (obj.hasOwnProperty(key) && obj[key]) {
+            classes.push(key);
+          }
         }
+
+        return classes.join(' ');
       }
 
-      return classes.join(' ');
-    }
+      Polymer({
 
-    Polymer({
+        is: 'paper-drawer-panel',
 
-      is: 'paper-drawer-panel',
-
-      /**
-       * Fired when the narrow layout changes.
-       *
-       * @event paper-responsive-change {{narrow: boolean}} detail -
-       *     narrow: true if the panel is in narrow layout.
-       */
-
-      /**
-       * Fired when the a panel is selected.
-       *
-       * Listening for this event is an alternative to observing changes in the `selected` attribute.
-       * This event is fired both when a panel is selected.
-       *
-       * @event iron-select {{item: Object}} detail -
-       *     item: The panel that the event refers to.
-       */
-
-      /**
-       * Fired when a panel is deselected.
-       *
-       * Listening for this event is an alternative to observing changes in the `selected` attribute.
-       * This event is fired both when a panel is deselected.
-       *
-       * @event iron-deselect {{item: Object}} detail -
-       *     item: The panel that the event refers to.
-       */
-      properties: {
+        behaviors: [Polymer.IronResizableBehavior],
 
         /**
-         * The panel to be selected when `paper-drawer-panel` changes to narrow
-         * layout.
+         * Fired when the narrow layout changes.
+         *
+         * @event paper-responsive-change {{narrow: boolean}} detail -
+         *     narrow: true if the panel is in narrow layout.
          */
-        defaultSelected: {
-          type: String,
-          value: 'main'
-        },
 
         /**
-         * If true, swipe from the edge is disable.
+         * Fired when the a panel is selected.
+         *
+         * Listening for this event is an alternative to observing changes in the `selected` attribute.
+         * This event is fired both when a panel is selected.
+         *
+         * @event iron-select {{item: Object}} detail -
+         *     item: The panel that the event refers to.
          */
-        disableEdgeSwipe: {
-          type: Boolean,
-          value: false
-        },
 
         /**
-         * If true, swipe to open/close the drawer is disabled.
+         * Fired when a panel is deselected.
+         *
+         * Listening for this event is an alternative to observing changes in the `selected` attribute.
+         * This event is fired both when a panel is deselected.
+         *
+         * @event iron-deselect {{item: Object}} detail -
+         *     item: The panel that the event refers to.
          */
-        disableSwipe: {
-          type: Boolean,
-          value: false
-        },
+        properties: {
 
-        /**
-         * Whether the user is dragging the drawer interactively.
-         */
-        dragging: {
-          type: Boolean,
-          value: false,
-          readOnly: true,
-          notify: true
-        },
+          /**
+           * The panel to be selected when `paper-drawer-panel` changes to narrow
+           * layout.
+           */
+          defaultSelected: {
+            type: String,
+            value: 'main'
+          },
 
-        /**
-         * Width of the drawer panel.
-         */
-        drawerWidth: {
-          type: String,
-          value: '256px'
-        },
+          /**
+           * If true, swipe from the edge is disabled.
+           */
+          disableEdgeSwipe: {
+            type: Boolean,
+            value: false
+          },
 
-        /**
-         * How many pixels on the side of the screen are sensitive to edge
-         * swipes and peek.
-         */
-        edgeSwipeSensitivity: {
-          type: Number,
-          value: 30
-        },
+          /**
+           * If true, swipe to open/close the drawer is disabled.
+           */
+          disableSwipe: {
+            type: Boolean,
+            value: false
+          },
 
-        /**
-         * If true, ignore `responsiveWidth` setting and force the narrow layout.
-         */
-        forceNarrow: {
-          type: Boolean,
-          value: false
-        },
+          /**
+           * Whether the user is dragging the drawer interactively.
+           */
+          dragging: {
+            type: Boolean,
+            value: false,
+            readOnly: true,
+            notify: true
+          },
 
-        /**
-         * Whether the browser has support for the transform CSS property.
-         */
-        hasTransform: {
-          type: Boolean,
-          value: function() {
-            return 'transform' in this.style;
-          }
-        },
+          /**
+           * Width of the drawer panel.
+           */
+          drawerWidth: {
+            type: String,
+            value: '256px'
+          },
 
-        /**
-         * Whether the browser has support for the will-change CSS property.
-         */
-        hasWillChange: {
-          type: Boolean,
-          value: function() {
-            return 'willChange' in this.style;
-          }
-        },
+          /**
+           * How many pixels on the side of the screen are sensitive to edge
+           * swipes and peek.
+           */
+          edgeSwipeSensitivity: {
+            type: Number,
+            value: 30
+          },
 
-        /**
-         * Returns true if the panel is in narrow layout.  This is useful if you
-         * need to show/hide elements based on the layout.
-         */
-        narrow: {
-          reflectToAttribute: true,
-          type: Boolean,
-          value: false,
-          readOnly: true,
-          notify: true
-        },
+          /**
+           * If true, ignore `responsiveWidth` setting and force the narrow layout.
+           */
+          forceNarrow: {
+            type: Boolean,
+            value: false
+          },
 
-        /**
-         * Whether the drawer is peeking out from the edge.
-         */
-        peeking: {
-          type: Boolean,
-          value: false,
-          readOnly: true,
-          notify: true
-        },
-
-        /**
-         * Max-width when the panel changes to narrow layout.
-         */
-        responsiveWidth: {
-          type: String,
-          value: '640px'
-        },
-
-        /**
-         * If true, position the drawer to the right.
-         */
-        rightDrawer: {
-          type: Boolean,
-          value: false
-        },
-
-        /**
-         * The panel that is being selected. `drawer` for the drawer panel and
-         * `main` for the main panel.
-         */
-        selected: {
-          reflectToAttribute: true,
-          notify: true,
-          type: String,
-          value: null
-        },
-
-        /**
-         * The attribute on elements that should toggle the drawer on tap, also elements will
-         * automatically be hidden in wide layout.
-         */
-        drawerToggleAttribute: {
-          type: String,
-          value: 'paper-drawer-toggle'
-        },
-
-        /**
-         * Whether the transition is enabled.
-         */
-        transition: {
-          type: Boolean,
-          value: false
-        },
-
-      },
-
-      listeners: {
-        tap: '_onTap',
-        track: '_onTrack',
-        down: '_downHandler',
-        up: '_upHandler'
-      },
-
-      observers: [
-        '_forceNarrowChanged(forceNarrow, defaultSelected)'
-      ],
-
-      /**
-       * Toggles the panel open and closed.
-       *
-       * @method togglePanel
-       */
-      togglePanel: function() {
-        if (this._isMainSelected()) {
-          this.openDrawer();
-        } else {
-          this.closeDrawer();
-        }
-      },
-
-      /**
-       * Opens the drawer.
-       *
-       * @method openDrawer
-       */
-      openDrawer: function() {
-        this.selected = 'drawer';
-      },
-
-      /**
-       * Closes the drawer.
-       *
-       * @method closeDrawer
-       */
-      closeDrawer: function() {
-        this.selected = 'main';
-      },
-
-      ready: function() {
-        // Avoid transition at the beginning e.g. page loads and enable
-        // transitions only after the element is rendered and ready.
-        this.transition = true;
-      },
-
-      _computeIronSelectorClass: function(narrow, transition, dragging, rightDrawer, peeking) {
-        return classNames({
-          dragging: dragging,
-          'narrow-layout': narrow,
-          'right-drawer': rightDrawer,
-          'left-drawer': !rightDrawer,
-          transition: transition,
-          peeking: peeking
-        });
-      },
-
-      _computeDrawerStyle: function(drawerWidth) {
-        return 'width:' + drawerWidth + ';';
-      },
-
-      _computeMainStyle: function(narrow, rightDrawer, drawerWidth) {
-        var style = '';
-
-        style += 'left:' + ((narrow || rightDrawer) ? '0' : drawerWidth) + ';';
-
-        if (rightDrawer) {
-          style += 'right:' + (narrow ? '' : drawerWidth) + ';';
-        }
-
-        return style;
-      },
-
-      _computeMediaQuery: function(forceNarrow, responsiveWidth) {
-        return forceNarrow ? '' : '(max-width: ' + responsiveWidth + ')';
-      },
-
-      _computeSwipeOverlayHidden: function(narrow, disableEdgeSwipe) {
-        return !narrow || disableEdgeSwipe;
-      },
-
-      _onTrack: function(event) {
-        if (sharedPanel && this !== sharedPanel) {
-          return;
-        }
-        switch (event.detail.state) {
-          case 'start':
-            this._trackStart(event);
-            break;
-          case 'track':
-            this._trackX(event);
-            break;
-          case 'end':
-            this._trackEnd(event);
-            break;
-        }
-
-      },
-
-      _responsiveChange: function(narrow) {
-        this._setNarrow(narrow);
-
-        if (this.narrow) {
-          this.selected = this.defaultSelected;
-        }
-
-        this.setScrollDirection(this._swipeAllowed() ? 'y' : 'all');
-        this.fire('paper-responsive-change', {narrow: this.narrow});
-      },
-
-      _onQueryMatchesChanged: function(event) {
-        this._responsiveChange(event.detail.value);
-      },
-
-      _forceNarrowChanged: function() {
-        // set the narrow mode only if we reached the `responsiveWidth`
-        this._responsiveChange(this.forceNarrow || this.$.mq.queryMatches);
-      },
-
-      _swipeAllowed: function() {
-        return this.narrow && !this.disableSwipe;
-      },
-
-      _isMainSelected: function() {
-        return this.selected === 'main';
-      },
-
-      _startEdgePeek: function() {
-        this.width = this.$.drawer.offsetWidth;
-        this._moveDrawer(this._translateXForDeltaX(this.rightDrawer ?
-            -this.edgeSwipeSensitivity : this.edgeSwipeSensitivity));
-        this._setPeeking(true);
-      },
-
-      _stopEdgePeek: function() {
-        if (this.peeking) {
-          this._setPeeking(false);
-          this._moveDrawer(null);
-        }
-      },
-
-      _downHandler: function(event) {
-        if (!this.dragging && this._isMainSelected() && this._isEdgeTouch(event) && !sharedPanel) {
-          this._startEdgePeek();
-          // cancel selection
-          event.preventDefault();
-          // grab this panel
-          sharedPanel = this;
-        }
-      },
-
-      _upHandler: function() {
-        this._stopEdgePeek();
-        // release the panel
-        sharedPanel = null;
-      },
-
-      _onTap: function(event) {
-        var targetElement = Polymer.dom(event).localTarget;
-        var isTargetToggleElement = targetElement &&
-          this.drawerToggleAttribute &&
-          targetElement.hasAttribute(this.drawerToggleAttribute);
-
-        if (isTargetToggleElement) {
-          this.togglePanel();
-        }
-      },
-
-      _isEdgeTouch: function(event) {
-        var x = event.detail.x;
-
-        return !this.disableEdgeSwipe && this._swipeAllowed() &&
-          (this.rightDrawer ?
-            x >= this.offsetWidth - this.edgeSwipeSensitivity :
-            x <= this.edgeSwipeSensitivity);
-      },
-
-      _trackStart: function(event) {
-        if (this._swipeAllowed()) {
-          sharedPanel = this;
-          this._setDragging(true);
-
-          if (this._isMainSelected()) {
-            this._setDragging(this.peeking || this._isEdgeTouch(event));
-          }
-
-          if (this.dragging) {
-            this.width = this.$.drawer.offsetWidth;
-            this.transition = false;
-          }
-        }
-      },
-
-      _translateXForDeltaX: function(deltaX) {
-        var isMain = this._isMainSelected();
-
-        if (this.rightDrawer) {
-          return Math.max(0, isMain ? this.width + deltaX : deltaX);
-        } else {
-          return Math.min(0, isMain ? deltaX - this.width : deltaX);
-        }
-      },
-
-      _trackX: function(event) {
-        if (this.dragging) {
-          var dx = event.detail.dx;
-
-          if (this.peeking) {
-            if (Math.abs(dx) <= this.edgeSwipeSensitivity) {
-              // Ignore trackx until we move past the edge peek.
-              return;
+          /**
+           * Whether the browser has support for the transform CSS property.
+           */
+          hasTransform: {
+            type: Boolean,
+            value: function() {
+              return 'transform' in this.style;
             }
-            this._setPeeking(false);
+          },
+
+          /**
+           * Whether the browser has support for the will-change CSS property.
+           */
+          hasWillChange: {
+            type: Boolean,
+            value: function() {
+              return 'willChange' in this.style;
+            }
+          },
+
+          /**
+           * Returns true if the panel is in narrow layout.  This is useful if you
+           * need to show/hide elements based on the layout.
+           */
+          narrow: {
+            reflectToAttribute: true,
+            type: Boolean,
+            value: false,
+            readOnly: true,
+            notify: true
+          },
+
+          /**
+           * Whether the drawer is peeking out from the edge.
+           */
+          peeking: {
+            type: Boolean,
+            value: false,
+            readOnly: true,
+            notify: true
+          },
+
+          /**
+           * Max-width when the panel changes to narrow layout.
+           */
+          responsiveWidth: {
+            type: String,
+            value: '600px'
+          },
+
+          /**
+           * If true, position the drawer to the right.
+           */
+          rightDrawer: {
+            type: Boolean,
+            value: false
+          },
+
+          /**
+           * The panel that is being selected. `drawer` for the drawer panel and
+           * `main` for the main panel.
+           */
+          selected: {
+            reflectToAttribute: true,
+            notify: true,
+            type: String,
+            value: null
+          },
+
+          /**
+           * The attribute on elements that should toggle the drawer on tap, also elements will
+           * automatically be hidden in wide layout.
+           */
+          drawerToggleAttribute: {
+            type: String,
+            value: 'paper-drawer-toggle'
+          },
+
+          /**
+           * Whether the transition is enabled.
+           */
+          transition: {
+            type: Boolean,
+            value: false
+          },
+
+        },
+
+        listeners: {
+          tap: '_onTap',
+          track: '_onTrack',
+          down: '_downHandler',
+          up: '_upHandler'
+        },
+
+        observers: [
+          '_forceNarrowChanged(forceNarrow, defaultSelected)'
+        ],
+
+        /**
+         * Toggles the panel open and closed.
+         *
+         * @method togglePanel
+         */
+        togglePanel: function() {
+          if (this._isMainSelected()) {
+            this.openDrawer();
+          } else {
+            this.closeDrawer();
+          }
+        },
+
+        /**
+         * Opens the drawer.
+         *
+         * @method openDrawer
+         */
+        openDrawer: function() {
+          this.selected = 'drawer';
+        },
+
+        /**
+         * Closes the drawer.
+         *
+         * @method closeDrawer
+         */
+        closeDrawer: function() {
+          this.selected = 'main';
+        },
+
+        ready: function() {
+          // Avoid transition at the beginning e.g. page loads and enable
+          // transitions only after the element is rendered and ready.
+          this.transition = true;
+        },
+
+        _onMainTransitionEnd: function (e) {
+          if (e.currentTarget === this.$.main && (e.propertyName === 'left' || e.propertyName === 'right')) {
+            this.notifyResize();
+          }
+        },
+
+        _computeIronSelectorClass: function(narrow, transition, dragging, rightDrawer, peeking) {
+          return classNames({
+            dragging: dragging,
+            'narrow-layout': narrow,
+            'right-drawer': rightDrawer,
+            'left-drawer': !rightDrawer,
+            transition: transition,
+            peeking: peeking
+          });
+        },
+
+        _computeDrawerStyle: function(drawerWidth) {
+          return 'width:' + drawerWidth + ';';
+        },
+
+        _computeMainStyle: function(narrow, rightDrawer, drawerWidth) {
+          var style = '';
+
+          style += 'left:' + ((narrow || rightDrawer) ? '0' : drawerWidth) + ';';
+
+          if (rightDrawer) {
+            style += 'right:' + (narrow ? '' : drawerWidth) + ';';
           }
 
-          this._moveDrawer(this._translateXForDeltaX(dx));
-        }
-      },
+          return style;
+        },
 
-      _trackEnd: function(event) {
-        if (this.dragging) {
-          var xDirection = event.detail.dx > 0;
+        _computeMediaQuery: function(forceNarrow, responsiveWidth) {
+          return forceNarrow ? '' : '(max-width: ' + responsiveWidth + ')';
+        },
 
-          this._setDragging(false);
-          this.transition = true;
+        _computeSwipeOverlayHidden: function(narrow, disableEdgeSwipe) {
+          return !narrow || disableEdgeSwipe;
+        },
+
+        _onTrack: function(event) {
+          if (sharedPanel && this !== sharedPanel) {
+            return;
+          }
+          switch (event.detail.state) {
+            case 'start':
+              this._trackStart(event);
+              break;
+            case 'track':
+              this._trackX(event);
+              break;
+            case 'end':
+              this._trackEnd(event);
+              break;
+          }
+
+        },
+
+        _responsiveChange: function(narrow) {
+          this._setNarrow(narrow);
+
+          if (this.narrow) {
+            this.selected = this.defaultSelected;
+          }
+
+          this.setScrollDirection(this._swipeAllowed() ? 'y' : 'all');
+          this.fire('paper-responsive-change', {narrow: this.narrow});
+        },
+
+        _onQueryMatchesChanged: function(event) {
+          this._responsiveChange(event.detail.value);
+        },
+
+        _forceNarrowChanged: function() {
+          // set the narrow mode only if we reached the `responsiveWidth`
+          this._responsiveChange(this.forceNarrow || this.$.mq.queryMatches);
+        },
+
+        _swipeAllowed: function() {
+          return this.narrow && !this.disableSwipe;
+        },
+
+        _isMainSelected: function() {
+          return this.selected === 'main';
+        },
+
+        _startEdgePeek: function() {
+          this.width = this.$.drawer.offsetWidth;
+          this._moveDrawer(this._translateXForDeltaX(this.rightDrawer ?
+              -this.edgeSwipeSensitivity : this.edgeSwipeSensitivity));
+          this._setPeeking(true);
+        },
+
+        _stopEdgePeek: function() {
+          if (this.peeking) {
+            this._setPeeking(false);
+            this._moveDrawer(null);
+          }
+        },
+
+        _downHandler: function(event) {
+          if (!this.dragging && this._isMainSelected() && this._isEdgeTouch(event) && !sharedPanel) {
+            this._startEdgePeek();
+            // cancel selection
+            event.preventDefault();
+            // grab this panel
+            sharedPanel = this;
+          }
+        },
+
+        _upHandler: function() {
+          this._stopEdgePeek();
+          // release the panel
           sharedPanel = null;
-          this._moveDrawer(null);
+        },
+
+        _onTap: function(event) {
+          var targetElement = Polymer.dom(event).localTarget;
+          var isTargetToggleElement = targetElement &&
+            this.drawerToggleAttribute &&
+            targetElement.hasAttribute(this.drawerToggleAttribute);
+
+          if (isTargetToggleElement) {
+            this.togglePanel();
+          }
+        },
+
+        _isEdgeTouch: function(event) {
+          var x = event.detail.x;
+
+          return !this.disableEdgeSwipe && this._swipeAllowed() &&
+            (this.rightDrawer ?
+              x >= this.offsetWidth - this.edgeSwipeSensitivity :
+              x <= this.edgeSwipeSensitivity);
+        },
+
+        _trackStart: function(event) {
+          if (this._swipeAllowed()) {
+            sharedPanel = this;
+            this._setDragging(true);
+
+            if (this._isMainSelected()) {
+              this._setDragging(this.peeking || this._isEdgeTouch(event));
+            }
+
+            if (this.dragging) {
+              this.width = this.$.drawer.offsetWidth;
+              this.transition = false;
+            }
+          }
+        },
+
+        _translateXForDeltaX: function(deltaX) {
+          var isMain = this._isMainSelected();
 
           if (this.rightDrawer) {
-            this[xDirection ? 'closeDrawer' : 'openDrawer']();
+            return Math.max(0, isMain ? this.width + deltaX : deltaX);
           } else {
-            this[xDirection ? 'openDrawer' : 'closeDrawer']();
+            return Math.min(0, isMain ? deltaX - this.width : deltaX);
           }
-        }
-      },
+        },
 
-      _transformForTranslateX: function(translateX) {
-        if (translateX === null) {
-          return '';
+        _trackX: function(event) {
+          if (this.dragging) {
+            var dx = event.detail.dx;
+
+            if (this.peeking) {
+              if (Math.abs(dx) <= this.edgeSwipeSensitivity) {
+                // Ignore trackx until we move past the edge peek.
+                return;
+              }
+              this._setPeeking(false);
+            }
+
+            this._moveDrawer(this._translateXForDeltaX(dx));
+          }
+        },
+
+        _trackEnd: function(event) {
+          if (this.dragging) {
+            var xDirection = event.detail.dx > 0;
+
+            this._setDragging(false);
+            this.transition = true;
+            sharedPanel = null;
+            this._moveDrawer(null);
+
+            if (this.rightDrawer) {
+              this[xDirection ? 'closeDrawer' : 'openDrawer']();
+            } else {
+              this[xDirection ? 'openDrawer' : 'closeDrawer']();
+            }
+          }
+        },
+
+        _transformForTranslateX: function(translateX) {
+          if (translateX === null) {
+            return '';
+          }
+
+          return this.hasWillChange ? 'translateX(' + translateX + 'px)' :
+              'translate3d(' + translateX + 'px, 0, 0)';
+        },
+
+        _moveDrawer: function(translateX) {
+          this.transform(this._transformForTranslateX(translateX), this.$.drawer);
         }
 
-        return this.hasWillChange ? 'translateX(' + translateX + 'px)' :
-            'translate3d(' + translateX + 'px, 0, 0)';
-      },
-
-      _moveDrawer: function(translateX) {
-        this.transform(this._transformForTranslateX(translateX), this.$.drawer);
-      }
-
-    });
-
-  }());
\ No newline at end of file
+      });
+    }());
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.css b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.css
deleted file mode 100644
index 747f0bb7..0000000
--- a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.css
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
-@license
-Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
-This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
-The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
-The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
-Code distributed by Google as part of the polymer project is also
-subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-*/
-
-:host {
-  display: block;
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  overflow: hidden;
-}
-
-iron-selector > #drawer {
-  position: absolute;
-  top: 0;
-  left: 0;
-  height: 100%;
-  background-color: white;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-
-  @apply(--paper-drawer-panel-drawer-container);
-}
-
-.transition > #drawer {
-  transition: -webkit-transform ease-in-out 0.3s, width ease-in-out 0.3s, visibility 0.3s;
-  transition: transform ease-in-out 0.3s, width ease-in-out 0.3s, visibility 0.3s;
-}
-
-.left-drawer > #drawer {
-  @apply(--paper-drawer-panel-left-drawer-container);
-}
-
-.right-drawer > #drawer {
-  left: auto;
-  right: 0;
-
-  @apply(--paper-drawer-panel-right-drawer-container);
-}
-
-iron-selector > #main {
-  position: absolute;
-  top: 0;
-  right: 0;
-  bottom: 0;
-
-  @apply(--paper-drawer-panel-main-container);
-}
-
-.transition > #main {
-  transition: left ease-in-out 0.3s, padding ease-in-out 0.3s;
-}
-
-.right-drawer > #main {
-  left: 0;
-}
-
-.right-drawer.transition > #main {
-  transition: right ease-in-out 0.3s, padding ease-in-out 0.3s;
-}
-
-#main > ::content > [main] {
-  height: 100%;
-}
-
-#drawer > ::content > [drawer] {
-  height: 100%;
-}
-
-#scrim {
-  position: absolute;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  visibility: hidden;
-  opacity: 0;
-  transition: opacity ease-in-out 0.38s, visibility ease-in-out 0.38s;
-  background-color: rgba(0, 0, 0, 0.3);
-}
-
-.narrow-layout > #drawer {
-  will-change: transform;
-}
-
-.narrow-layout > #drawer.iron-selected {
-  box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
-}
-
-.right-drawer.narrow-layout > #drawer.iron-selected {
-  box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.15);
-}
-
-.narrow-layout > #drawer > ::content > [drawer] {
-  border: 0;
-}
-
-.left-drawer.narrow-layout > #drawer:not(.iron-selected) {
-  -webkit-transform: translateX(-100%);
-  transform: translateX(-100%);
-}
-
-.right-drawer.narrow-layout > #drawer:not(.iron-selected) {
-  left: auto;
-  visibility: hidden;
-
-  -webkit-transform: translateX(100%);
-  transform: translateX(100%);
-}
-
-.right-drawer.narrow-layout.dragging > #drawer:not(.iron-selected),
-.right-drawer.narrow-layout.peeking > #drawer:not(.iron-selected) {
-  visibility: visible;
-}
-
-.narrow-layout > #main {
-  padding: 0;
-}
-
-.right-drawer.narrow-layout > #main {
-  left: 0;
-  right: 0;
-}
-
-.narrow-layout > #main:not(.iron-selected) > #scrim,
-.dragging > #main > #scrim {
-  visibility: visible;
-  opacity: var(--paper-drawer-panel-scrim-opacity, 1);
-}
-
-.narrow-layout > #main > * {
-  margin: 0;
-  min-height: 100%;
-  left: 0;
-  right: 0;
-
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-}
-
-iron-selector:not(.narrow-layout) #main ::content [paper-drawer-toggle] {
-  display: none;
-}
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.html b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.html
index e334999..99f38e1 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.html
@@ -8,8 +8,11 @@
 --><html><head><link rel="import" href="../polymer/polymer.html">
 <link rel="import" href="../iron-media-query/iron-media-query.html">
 <link rel="import" href="../iron-selector/iron-selector.html">
+<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
 
 <!--
+Material design: [Navigation drawer](https://www.google.com/design/spec/patterns/navigation-drawer.html)
+
 `paper-drawer-panel` contains a drawer panel and a main panel.  The drawer
 and the main panel are side-by-side with drawer on the left.  When the browser
 window size is smaller than the `responsiveWidth`, `paper-drawer-panel`
@@ -72,7 +75,7 @@
       <div main> Main panel... </div>
     </paper-drawer-panel>
 
-Styling `paper-drawer-panel`
+### Styling
 
 To change the main container:
 
@@ -98,6 +101,25 @@
       };
     }
 
+To customize the scrim:
+
+    paper-drawer-panel {
+      --paper-drawer-panel-scrim: {
+        background-color: red;
+      };
+    }
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-drawer-panel-scrim-opacity` | Scrim opacity | 1
+`--paper-drawer-panel-drawer-container` | Mixin applied to drawer container | {}
+`--paper-drawer-panel-left-drawer-container` | Mixin applied to container when it's in the left side | {}
+`--paper-drawer-panel-main-container` | Mixin applied to main container | {}
+`--paper-drawer-panel-right-drawer-container` | Mixin applied to container when it's in the right side | {}
+`--paper-drawer-panel-scrim` | Mixin applied to scrim | {}
+
 @group Paper elements
 @element paper-drawer-panel
 @demo demo/index.html
@@ -105,15 +127,160 @@
 -->
 
 </head><body><dom-module id="paper-drawer-panel">
-  <link rel="import" type="css" href="paper-drawer-panel.css">
-
   <template>
+    <style>
+      :host {
+        display: block;
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+      }
+
+      iron-selector > #drawer {
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 100%;
+        background-color: white;
+
+        -moz-box-sizing: border-box;
+        box-sizing: border-box;
+
+        @apply(--paper-drawer-panel-drawer-container);
+      }
+
+      .transition > #drawer {
+        transition: -webkit-transform ease-in-out 0.3s, width ease-in-out 0.3s, visibility 0.3s;
+        transition: transform ease-in-out 0.3s, width ease-in-out 0.3s, visibility 0.3s;
+      }
+
+      .left-drawer > #drawer {
+        @apply(--paper-drawer-panel-left-drawer-container);
+      }
+
+      .right-drawer > #drawer {
+        left: auto;
+        right: 0;
+
+        @apply(--paper-drawer-panel-right-drawer-container);
+      }
+
+      iron-selector > #main {
+        position: absolute;
+        top: 0;
+        right: 0;
+        bottom: 0;
+
+        @apply(--paper-drawer-panel-main-container);
+      }
+
+      .transition > #main {
+        transition: left ease-in-out 0.3s, padding ease-in-out 0.3s;
+      }
+
+      .right-drawer > #main {
+        left: 0;
+      }
+
+      .right-drawer.transition > #main {
+        transition: right ease-in-out 0.3s, padding ease-in-out 0.3s;
+      }
+
+      #main > ::content > [main] {
+        height: 100%;
+      }
+
+      #drawer > ::content > [drawer] {
+        height: 100%;
+      }
+
+      #scrim {
+        position: absolute;
+        top: 0;
+        right: 0;
+        bottom: 0;
+        left: 0;
+        visibility: hidden;
+        opacity: 0;
+        transition: opacity ease-in-out 0.38s, visibility ease-in-out 0.38s;
+        background-color: rgba(0, 0, 0, 0.3);
+
+        @apply(--paper-drawer-panel-scrim);
+      }
+
+      .narrow-layout > #drawer {
+        will-change: transform;
+      }
+
+      .narrow-layout > #drawer.iron-selected {
+        box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
+      }
+
+      .right-drawer.narrow-layout > #drawer.iron-selected {
+        box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.15);
+      }
+
+      .narrow-layout > #drawer > ::content > [drawer] {
+        border: 0;
+      }
+
+      .left-drawer.narrow-layout > #drawer:not(.iron-selected) {
+        -webkit-transform: translateX(-100%);
+        transform: translateX(-100%);
+      }
+
+      .right-drawer.narrow-layout > #drawer:not(.iron-selected) {
+        left: auto;
+        visibility: hidden;
+
+        -webkit-transform: translateX(100%);
+        transform: translateX(100%);
+      }
+
+      .right-drawer.narrow-layout.dragging > #drawer:not(.iron-selected),
+      .right-drawer.narrow-layout.peeking > #drawer:not(.iron-selected) {
+        visibility: visible;
+      }
+
+      .narrow-layout > #main {
+        padding: 0;
+      }
+
+      .right-drawer.narrow-layout > #main {
+        left: 0;
+        right: 0;
+      }
+
+      .narrow-layout > #main:not(.iron-selected) > #scrim,
+      .dragging > #main > #scrim {
+        visibility: visible;
+        opacity: var(--paper-drawer-panel-scrim-opacity, 1);
+      }
+
+      .narrow-layout > #main > * {
+        margin: 0;
+        min-height: 100%;
+        left: 0;
+        right: 0;
+
+        -moz-box-sizing: border-box;
+        box-sizing: border-box;
+      }
+
+      iron-selector:not(.narrow-layout) #main ::content [paper-drawer-toggle] {
+        display: none;
+      }
+    </style>
+
     <iron-media-query id="mq" on-query-matches-changed="_onQueryMatchesChanged" query="[[_computeMediaQuery(forceNarrow, responsiveWidth)]]">
     </iron-media-query>
 
     <iron-selector attr-for-selected="id" class$="[[_computeIronSelectorClass(narrow, transition, dragging, rightDrawer, peeking)]]" activate-event="" selected="[[selected]]">
 
-      <div id="main" style$="[[_computeMainStyle(narrow, rightDrawer, drawerWidth)]]">
+      <div id="main" style$="[[_computeMainStyle(narrow, rightDrawer, drawerWidth)]]" on-transitionend="_onMainTransitionEnd">
         <content select="[main]"></content>
         <div id="scrim" on-tap="closeDrawer"></div>
       </div>
@@ -125,6 +292,5 @@
     </iron-selector>
   </template>
 
-</dom-module>
-
+  </dom-module>
 <script src="paper-drawer-panel-extracted.js"></script></body></html>
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/.bower.json
index 5c1c975ae..4c53435 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-dropdown-menu",
-  "version": "1.0.4",
+  "version": "1.1.0",
   "description": "An element that works similarly to a native browser select",
   "authors": [
     "The Polymer Authors"
@@ -28,23 +28,25 @@
     "paper-input": "polymerelements/paper-input#^1.0.9",
     "paper-menu-button": "polymerelements/paper-menu-button#^1.0.0",
     "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
-    "paper-styles": "polymerelements/paper-styles#^1.0.0"
+    "paper-styles": "polymerelements/paper-styles#^1.0.0",
+    "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+    "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0"
   },
   "devDependencies": {
     "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
     "test-fixture": "polymerelements/test-fixture#^1.0.0",
     "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
     "paper-item": "polymerelements/paper-item#^1.0.0",
-    "paper-menu": "polymerelements/paper-menu#^1.0.0",
+    "paper-listbox": "polymerelements/paper-listbox#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
     "web-component-tester": "*",
     "paper-tabs": "polymerelements/paper-tabs#^1.0.0"
   },
-  "_release": "1.0.4",
+  "_release": "1.1.0",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.4",
-    "commit": "b278c9ea1b3642c77bd4597a28b39a61996a5a9e"
+    "tag": "v1.1.0",
+    "commit": "f8255435fe62219f4f4d5991651aba623cbf50e2"
   },
   "_source": "git://github.com/PolymerElements/paper-dropdown-menu.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/.travis.yml b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/.travis.yml
new file mode 100644
index 0000000..c9383b47
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: Uv6d6W9yI2Lbj7gYh73LCGHpwvvdE1sdqdElVsTN4LSYW4msyLweDD4/Irbk5Nw5bavxkXraYkN655p5VU1SBucTRFMYYtpTDA7xBT/HvXVP3+OgkrN+joVStHcRJXHJCoVtq+YalZ07Q0dltw/brtSUCHhZkcNMxHd/p0NGD1FBSgXC1oXv+MSLjPsSKujz8WuXbfnGXkW682rZhS8Mp5x4Y31AAuGl64gNypAYTdWZ9bKLjeAx4ZY1poiw4Bs1z+V9tO3EeD6YQb/CVpxOH+67FQ2cX0ybLXumNuJQFIzki+EzFwXxuKrJsD4gu8B4kJKVWuAS9wuWkNgGdjR2HVe3/5+nMe7RiLL/wD6yGvcD2ZjP8S0RrxbOeZ03IzadH1NT0FWGf0J55VQgt4XjN0j9bVTYMfX5Xyg5bQ/E1qPzHbyteMAw6LF4Wmh2PyWzKHfz1uPGiZP/3BOKj8EbGMKPBci2181kbotPDENMT/5lk24e944tr7hKWWatNxCmkeb+lJomAxGwDYt2+I4mrpHFz/r4w9qgNr3DelhHTkBw2lNKzGAL5I177IJvsvGnZaCpGuRDWfq2xLGg2aTa9J1iyvil8gQP4CVxffWbqpPxvOax3V5nfbnAUpyYWvCtVSpOV5ndZA9FlBIn/pOsXqIjdiOTmmeJwFoddpCcZ1Y=
+  - secure: X0QrO1SQJs/ktfeJRfAzSTTAyLeMLu0NB5uj+hQCLPZ6QPacaOEaKmwx57CY2qsD9X34ijtXZHP8A3RWKXeQHt2H4CrQ/drWWzNjKMmaf42w8fzHNKkqlwsQV7Bh/g5qXnbzrkcsViOfDVkyPLIKumyG2NqZPrhjl8QDMGseiELB5oznBH/z8APY3lJVB1baT3Wxyzz7TdAYCpZGfdGjr/3bAx1qBNHJXeEMFJDYH4q2nKfqVhdNQx2VdB6nyxIoGKoDynPIGty2pVPOKrp6ctdJYFwtljbO1/AOh3uvkiZRB1dAwr8vE6xVBcUnpM8vseRhlipCSO6qcNTolF67DzlakjxNd8CUwnokJ1juxH9x4uUTAaUpaAHOFqL130Ogcqye6KJ4RavD9cs198dZE3Al9savUF8N2Q8Mpc04dc7AuMOglTTQqhIpLSdtFWsIptMUmhBS3hMgWfVAH7DEzR41SFwwXCN4ZvYC1ooCJK1+wL2po4kIHRaEHx+L6r+1+RKXQ+zBAG5VMtFtc0OoFtInTvyNqBcyHGkbxQaGdHN1FpBWo3wL5qcP37DtYbGe0iEtASk1w0MLlujQjHIY4smxVB/XmNRiOEkWHAtGxbBOu4NAHU5Qhxe22/w1fgPnO3YRoiNO4liJEYJNN1TpTYO3VolNq0IvdFKswj/p0vM=
diff --git a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/README.md b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/README.md
index dc765e3..e66054d 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/README.md
+++ b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/README.md
@@ -1,28 +1,49 @@
-paper-dropdown-menu
-===================
+
+<!---
+
+This README is automatically generated from the comments in these files:
+paper-dropdown-menu.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/paper-dropdown-menu)_
+
+
+##&lt;paper-dropdown-menu&gt;
+
+
+Material design: [Dropdown menus](https://www.google.com/design/spec/components/buttons.html#buttons-dropdown-buttons)
 
 `paper-dropdown-menu` is similar to a native browser select element.
 `paper-dropdown-menu` works with selectable content. The currently selected
 item is displayed in the control. If no item is selected, the `label` is
 displayed instead.
+
 The child element with the class `dropdown-content` will be used as the dropdown
-menu. It could be a `paper-menu` or element that triggers `iron-activate` when
+menu. It could be a `paper-menu` or element that triggers `iron-select` when
 selecting its children.
+
 Example:
 
-```html
-<paper-dropdown-menu label="Your favourite pastry">
-  <paper-menu class="dropdown-content">
-    <paper-item>Croissant</paper-item>
-    <paper-item>Donut</paper-item>
-    <paper-item>Financier</paper-item>
-    <paper-item>Madeleine</paper-item>
-  </paper-menu>
-</paper-dropdown-menu>
-```
-    
+    <paper-dropdown-menu label="Your favourite pastry">
+      <paper-menu class="dropdown-content">
+        <paper-item>Croissant</paper-item>
+        <paper-item>Donut</paper-item>
+        <paper-item>Financier</paper-item>
+        <paper-item>Madeleine</paper-item>
+      </paper-menu>
+    </paper-dropdown-menu>
+
 This example renders a dropdown menu with 4 options.
+
+Similarly to using `iron-select`, `iron-deselect` events will cause the
+current selection of the `paper-dropdown-menu` to be cleared.
+
 ### Styling
+
 The following custom properties and mixins are also available for styling:
 
 Custom property | Description | Default
@@ -33,6 +54,9 @@
 `--paper-dropdown-menu-button` | A mixin that is applied to the internal menu button | `{}`
 `--paper-dropdown-menu-input` | A mixin that is applied to the internal paper input | `{}`
 `--paper-dropdown-menu-icon` | A mixin that is applied to the internal icon | `{}`
+
 You can also use any of the `paper-input-container` and `paper-menu-button`
 style mixins and custom properties to style the internal input and menu button
 respectively.
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/bower.json b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/bower.json
index fa482aa..ad433105 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-dropdown-menu",
-  "version": "1.0.4",
+  "version": "1.1.0",
   "description": "An element that works similarly to a native browser select",
   "authors": [
     "The Polymer Authors"
@@ -28,14 +28,16 @@
     "paper-input": "polymerelements/paper-input#^1.0.9",
     "paper-menu-button": "polymerelements/paper-menu-button#^1.0.0",
     "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
-    "paper-styles": "polymerelements/paper-styles#^1.0.0"
+    "paper-styles": "polymerelements/paper-styles#^1.0.0",
+    "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+    "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0"
   },
   "devDependencies": {
     "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
     "test-fixture": "polymerelements/test-fixture#^1.0.0",
     "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
     "paper-item": "polymerelements/paper-item#^1.0.0",
-    "paper-menu": "polymerelements/paper-menu#^1.0.0",
+    "paper-listbox": "polymerelements/paper-listbox#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
     "web-component-tester": "*",
     "paper-tabs": "polymerelements/paper-tabs#^1.0.0"
diff --git a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu-extracted.js
index 13a23ca..df298a0 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu-extracted.js
@@ -18,7 +18,9 @@
 
       behaviors: [
         Polymer.IronControlState,
-        Polymer.IronButtonState
+        Polymer.IronButtonState,
+        Polymer.IronFormElementBehavior,
+        Polymer.IronValidatableBehavior
       ],
 
       properties: {
@@ -30,7 +32,7 @@
         selectedItemLabel: {
           type: String,
           notify: true,
-          computed: '_computeSelectedItemLabel(selectedItem)'
+          readOnly: true
         },
 
         /**
@@ -47,6 +49,17 @@
         },
 
         /**
+         * The value for this element that will be used when submitting in
+         * a form. It is read only, and will always have the same value
+         * as `selectedItemLabel`.
+         */
+        value: {
+          type: String,
+          notify: true,
+          readOnly: true
+        },
+
+        /**
          * The label for the dropdown.
          */
         label: {
@@ -66,7 +79,8 @@
         opened: {
           type: Boolean,
           notify: true,
-          value: false
+          value: false,
+          observer: '_openedChanged'
         },
 
         /**
@@ -108,10 +122,15 @@
       },
 
       hostAttributes: {
-        role: 'group',
+        role: 'combobox',
+        'aria-autocomplete': 'none',
         'aria-haspopup': 'true'
       },
 
+      observers: [
+        '_selectedItemChanged(selectedItem)'
+      ],
+
       attached: function() {
         // NOTE(cdata): Due to timing, a preselected value in a `IronSelectable`
         // child will cause an `iron-select` event to fire while the element is
@@ -179,12 +198,16 @@
        * @param {Element} selectedItem A selected Element item, with an
        * optional `label` property.
        */
-      _computeSelectedItemLabel: function(selectedItem) {
+      _selectedItemChanged: function(selectedItem) {
+        var value = '';
         if (!selectedItem) {
-          return '';
+          value = '';
+        } else {
+          value = selectedItem.label || selectedItem.textContent.trim();
         }
 
-        return selectedItem.label || selectedItem.textContent.trim();
+        this._setValue(value);
+        this._setSelectedItemLabel(value);
       },
 
       /**
@@ -199,7 +222,25 @@
         // derived from the metrics of elements internal to `paper-input`'s
         // template. The metrics will change depending on whether or not the
         // input has a floating label.
-        return noLabelFloat ? -4 : 16;
+        return noLabelFloat ? -4 : 8;
+      },
+
+      /**
+       * Returns false if the element is required and does not have a selection,
+       * and true otherwise.
+       * @return {boolean} true if `required` is false, or if `required` is true
+       * and the element has a valid selection.
+       */
+      _getValidity: function() {
+        return this.disabled || !this.required || (this.required && this.value);
+      },
+
+      _openedChanged: function() {
+        var openState = this.opened ? 'true' : 'false';
+        var e = this.contentElement;
+        if (e) {
+          e.setAttribute('aria-expanded', openState);
+        }
       }
     });
   })();
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu.html b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu.html
index 00f23b14..5874b785 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-dropdown-menu/paper-dropdown-menu.html
@@ -17,8 +17,12 @@
 <link rel="import" href="../iron-icons/iron-icons.html">
 <link rel="import" href="../iron-icon/iron-icon.html">
 <link rel="import" href="../iron-selector/iron-selectable.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.html">
 
 <!--
+Material design: [Dropdown menus](https://www.google.com/design/spec/components/buttons.html#buttons-dropdown-buttons)
+
 `paper-dropdown-menu` is similar to a native browser select element.
 `paper-dropdown-menu` works with selectable content. The currently selected
 item is displayed in the control. If no item is selected, the `label` is
@@ -106,16 +110,17 @@
     }
 
     paper-ripple {
-      top: 20px;
-      left: 8px;
-      bottom: 16px;
-      right: 8px;
+      top: 12px;
+      left: 0px;
+      bottom: 8px;
+      right: 0px;
 
       @apply(--paper-dropdown-menu-ripple);
     }
 
     paper-menu-button {
       display: block;
+      padding: 0;
       @apply(--paper-dropdown-menu-button);
     }
 
@@ -131,10 +136,13 @@
 
   </style>
   <template>
+    <!-- this div fulfills an a11y requirement for combobox, do not remove -->
+    <div role="button"></div>
     <paper-menu-button id="menuButton" vertical-align="top" horizontal-align="right" vertical-offset="[[_computeMenuVerticalOffset(noLabelFloat)]]" disabled="[[disabled]]" no-animations="[[noAnimations]]" on-iron-select="_onIronSelect" on-iron-deselect="_onIronDeselect" opened="{{opened}}">
       <div class="dropdown-trigger">
         <paper-ripple></paper-ripple>
-        <paper-input readonly="" disabled="[[disabled]]" value="[[selectedItemLabel]]" placeholder="[[placeholder]]" always-float-label="[[alwaysFloatLabel]]" no-label-float="[[noLabelFloat]]" label="[[label]]">
+        <!-- paper-input has type="text" for a11y, do not remove -->
+        <paper-input type="text" invalid="[[invalid]]" readonly="" disabled="[[disabled]]" value="[[selectedItemLabel]]" placeholder="[[placeholder]]" always-float-label="[[alwaysFloatLabel]]" no-label-float="[[noLabelFloat]]" label="[[label]]">
           <iron-icon icon="arrow-drop-down" suffix=""></iron-icon>
         </paper-input>
       </div>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-fab/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-fab/.bower.json
index ac89bd36..2731e4d 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-fab/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-fab/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-fab",
-  "version": "1.0.5",
+  "version": "1.0.6",
   "description": "A material design floating action button",
   "authors": [
     "The Polymer Authors"
@@ -15,32 +15,32 @@
   "private": true,
   "repository": {
     "type": "git",
-    "url": "git://github.com/PolymerElements/paper-fab"
+    "url": "git://github.com/PolymerElements/paper-fab.git"
   },
   "license": "http://polymer.github.io/LICENSE.txt",
   "homepage": "https://github.com/PolymerElements/paper-fab",
   "dependencies": {
-    "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
-    "paper-material": "polymerelements/paper-material#^1.0.0",
-    "paper-behaviors": "polymerelements/paper-behaviors#^1.0.0",
-    "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
-    "iron-icon": "polymerelements/iron-icon#^1.0.0",
-    "iron-icons": "polymerelements/iron-icons#^1.0.0",
-    "paper-styles": "polymerelements/paper-styles#^1.0.0",
+    "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+    "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+    "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+    "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+    "paper-material": "PolymerElements/paper-material#^1.0.0",
+    "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+    "paper-styles": "PolymerElements/paper-styles#^1.0.0",
     "polymer": "Polymer/polymer#^1.0.0"
   },
   "devDependencies": {
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
-    "test-fixture": "polymerelements/test-fixture#^1.0.0",
-    "paper-styles": "polymerelements/paper-styles#^1.0.0",
+    "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.5",
+  "_release": "1.0.6",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.5",
-    "commit": "2f1cebbceeb76b5f48f2d82ea02001e0725d2d6e"
+    "tag": "v1.0.6",
+    "commit": "d9d70a86af8464f880d3022bedc08845c3bf2d1d"
   },
   "_source": "git://github.com/PolymerElements/paper-fab.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-fab/bower.json b/third_party/polymer/v1_0/components-chromium/paper-fab/bower.json
index 2c1a0f5..a9240a0 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-fab/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-fab/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-fab",
-  "version": "1.0.5",
+  "version": "1.0.6",
   "description": "A material design floating action button",
   "authors": [
     "The Polymer Authors"
@@ -15,24 +15,24 @@
   "private": true,
   "repository": {
     "type": "git",
-    "url": "git://github.com/PolymerElements/paper-fab"
+    "url": "git://github.com/PolymerElements/paper-fab.git"
   },
   "license": "http://polymer.github.io/LICENSE.txt",
   "homepage": "https://github.com/PolymerElements/paper-fab",
   "dependencies": {
-    "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
-    "paper-material": "polymerelements/paper-material#^1.0.0",
-    "paper-behaviors": "polymerelements/paper-behaviors#^1.0.0",
-    "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
-    "iron-icon": "polymerelements/iron-icon#^1.0.0",
-    "iron-icons": "polymerelements/iron-icons#^1.0.0",
-    "paper-styles": "polymerelements/paper-styles#^1.0.0",
+    "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+    "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+    "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+    "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+    "paper-material": "PolymerElements/paper-material#^1.0.0",
+    "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+    "paper-styles": "PolymerElements/paper-styles#^1.0.0",
     "polymer": "Polymer/polymer#^1.0.0"
   },
   "devDependencies": {
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
-    "test-fixture": "polymerelements/test-fixture#^1.0.0",
-    "paper-styles": "polymerelements/paper-styles#^1.0.0",
+    "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
     "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-fab/paper-fab-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-fab/paper-fab-extracted.js
index fb05b22..e2e94d3 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-fab/paper-fab-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-fab/paper-fab-extracted.js
@@ -46,5 +46,4 @@
         reflectToAttribute: true
       }
     }
-
   });
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-fab/paper-fab.html b/third_party/polymer/v1_0/components-chromium/paper-fab/paper-fab.html
index d23bf01..e622143 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-fab/paper-fab.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-fab/paper-fab.html
@@ -7,13 +7,13 @@
 Code distributed by Google as part of the polymer project is also
 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 --><html><head><link rel="import" href="../polymer/polymer.html">
-<link rel="import" href="../iron-icon/iron-icon.html">
 <link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
-<link rel="import" href="../paper-styles/default-theme.html">
-<link rel="import" href="../paper-styles/color.html">
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../paper-behaviors/paper-button-behavior.html">
 <link rel="import" href="../paper-material/paper-material.html">
 <link rel="import" href="../paper-ripple/paper-ripple.html">
-<link rel="import" href="../paper-behaviors/paper-button-behavior.html">
+<link rel="import" href="../paper-styles/color.html">
+<link rel="import" href="../paper-styles/default-theme.html">
 
 <!--
 Material design: [Floating Action Button](https://www.google.com/design/spec/components/buttons-floating-action-button.html)
@@ -57,7 +57,6 @@
 </head><body><dom-module id="paper-fab">
   <template strip-whitespace="">
     <style include="paper-material">
-
       :host {
         display: inline-block;
         position: relative;
@@ -107,7 +106,9 @@
         background: var(--paper-fab-keyboard-focus-background, --paper-pink-900);
       }
     </style>
+
     <iron-icon id="icon" src="[[src]]" icon="[[icon]]"></iron-icon>
   </template>
 </dom-module>
+
 <script src="paper-fab-extracted.js"></script></body></html>
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-input/.bower.json
index b3666ae..706b40f 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-input",
-  "version": "1.0.15",
+  "version": "1.0.18",
   "description": "Material design text fields",
   "authors": [
     "The Polymer Authors"
@@ -27,7 +27,7 @@
   "homepage": "https://github.com/PolymerElements/paper-input",
   "ignore": [],
   "dependencies": {
-    "polymer": "Polymer/polymer#^1.1.0",
+    "polymer": "Polymer/polymer#^1.2.0",
     "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0",
     "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
     "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
@@ -44,11 +44,11 @@
     "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
     "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0"
   },
-  "_release": "1.0.15",
+  "_release": "1.0.18",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.15",
-    "commit": "34d19454e0ea13b1a809add8c87fba128fbc9940"
+    "tag": "v1.0.18",
+    "commit": "8bb2b1972158d3a28ca3a350003b8ca78c147b53"
   },
   "_source": "git://github.com/PolymerElements/paper-input.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/bower.json b/third_party/polymer/v1_0/components-chromium/paper-input/bower.json
index 887a7442..09aace46 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-input",
-  "version": "1.0.15",
+  "version": "1.0.18",
   "description": "Material design text fields",
   "authors": [
     "The Polymer Authors"
@@ -27,7 +27,7 @@
   "homepage": "https://github.com/PolymerElements/paper-input",
   "ignore": [],
   "dependencies": {
-    "polymer": "Polymer/polymer#^1.1.0",
+    "polymer": "Polymer/polymer#^1.2.0",
     "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0",
     "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
     "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-behavior-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-behavior-extracted.js
index 19163b3..fc225a47 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-behavior-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-behavior-extracted.js
@@ -77,7 +77,7 @@
       },
 
       /**
-       * The datalist of the input (if any). This should match the id of an existing <datalist>. Bind this
+       * The datalist of the input (if any). This should match the id of an existing `<datalist>`. Bind this
        * to the `<input is="iron-input">`'s `list` property.
        */
       list: {
@@ -279,6 +279,20 @@
         type: Number
       },
 
+      /**
+       * Bind this to the `<input is="iron-input">`'s `accept` property, , used with type=file.
+       */
+      accept: {
+        type: String
+      },
+
+      /**
+       * Bind this to the `<input is="iron-input">`'s `multiple` property, , used with type=file.
+       */
+      multiple: {
+        type: Boolean
+      },
+
       _ariaDescribedBy: {
         type: String,
         value: ''
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-char-counter.html b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-char-counter.html
index 521475ed..786b580 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-char-counter.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-char-counter.html
@@ -38,6 +38,10 @@
         @apply(--paper-font-caption);
         @apply(--paper-input-char-counter);
       }
+
+      :host-context([dir="rtl"]) {
+        float: left;
+      }
     </style>
 
     <span>[[_charCounterStr]]</span>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container-extracted.js
index 77229ff..731dd48a 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container-extracted.js
@@ -142,6 +142,21 @@
       } else {
         this._handleValue(this._inputElement);
       }
+
+      this._numberOfPrefixNodes = 0;
+      this._prefixObserver = Polymer.dom(this.$.prefix).observeNodes(
+          function(mutations) {
+            // Keep track whether there's at least one prefix node, since it
+            // affects laying out the floating label.
+            this._numberOfPrefixNodes += mutations.addedNodes.length -
+                mutations.removedNodes.length;
+          }.bind(this));
+    },
+
+    detached: function() {
+      if (this._prefixObserver) {
+        Polymer.dom(this.$.prefix).unobserveNodes(this._prefixObserver);
+      }
     },
 
     _onAddonAttached: function(event) {
@@ -238,16 +253,15 @@
           } else if (focused) {
             cls += " label-is-highlighted";
           }
-          // The label might have a horizontal offset if a prefix element exists
+          // If a prefix element exists, the label has a horizontal offset
           // which needs to be undone when displayed as a floating label.
-          if (Polymer.dom(this.$.prefix).getDistributedNodes().length > 0 &&
-              label && label.offsetParent) {
-            label.style.left = -label.offsetParent.offsetLeft + 'px';
+          if (this._numberOfPrefixNodes > 0) {
+            this.$.labelAndInputContainer.style.position = 'static';
           }
         } else {
           // When the label is not floating, it should overlap the input element.
           if (label) {
-            label.style.left = 0;
+            this.$.labelAndInputContainer.style.position = 'relative';
           }
         }
       } else {
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container.html b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container.html
index 820de197..f81035f 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-container.html
@@ -73,15 +73,15 @@
 `--paper-input-container-invalid-color` | Label and underline color when the input is is invalid | `--google-red-500`
 `--paper-input-container-input-color` | Input foreground color | `--primary-text-color`
 `--paper-input-container` | Mixin applied to the container | `{}`
+`--paper-input-container-disabled` | Mixin applied to the container when it's disabled | `{}`
 `--paper-input-container-label` | Mixin applied to the label | `{}`
 `--paper-input-container-label-focus` | Mixin applied to the label when the input is focused | `{}`
 `--paper-input-container-input` | Mixin applied to the input | `{}`
-`--paper-input-container-input-disabled` | Mixin applied to the input when it's disabled | `{}`
-`--paper-input-container-prefix` | Mixin applied to the input prefix | `{}`
-`--paper-input-container-suffix` | Mixin applied to the input suffix | `{}`
 `--paper-input-container-underline` | Mixin applied to the underline | `{}`
 `--paper-input-container-underline-focus` | Mixin applied to the underline when the input is focued | `{}`
 `--paper-input-container-underline-disabled` | Mixin applied to the underline when the input is disabled | `{}`
+`--paper-input-prefix` | Mixin applied to the input prefix | `{}`
+`--paper-input-suffix` | Mixin applied to the input suffix | `{}`
 
 This element is `display:block` by default, but you can set the `inline` attribute to make it
 `display:inline-block`.
@@ -184,6 +184,7 @@
         font: inherit;
         color: var(--paper-input-container-color, --secondary-text-color);
 
+        @apply(--paper-font-common-nowrap);
         @apply(--paper-font-subhead);
         @apply(--paper-input-container-label);
       }
@@ -192,14 +193,29 @@
       .input-content.label-is-floating ::content .paper-input-label {
         -webkit-transform: translateY(-75%) scale(0.75);
         transform: translateY(-75%) scale(0.75);
-        -webkit-transform-origin: left top;
-        transform-origin: left top;
         -webkit-transition: -webkit-transform 0.25s;
         transition: transform 0.25s;
 
+        -webkit-transform-origin: left top;
+        transform-origin: left top;
+
+        /* Since we scale to 75/100 of the size, we actually have 100/75 of the
+        original space now available */
+        width: 133%;
+
         @apply(--paper-transition-easing);
       }
 
+      :host-context([dir="rtl"]) .input-content.label-is-floating ::content label,
+      :host-context([dir="rtl"]) .input-content.label-is-floating ::content .paper-input-label {
+        /* TODO(noms): Figure out why leaving the width at 133% before the animation
+         * actually makes
+         * it wider on the right side, not left side, as you would expect in RTL */
+        width: 100%;
+        -webkit-transform-origin: right top;
+        transform-origin: right top;
+      }
+
       .input-content.label-is-highlighted ::content label,
       .input-content.label-is-highlighted ::content .paper-input-label {
         color: var(--paper-input-container-focus-color, --default-primary-color);
@@ -230,6 +246,7 @@
         border: none;
         color: var(--paper-input-container-input-color, --primary-text-color);
         -webkit-appearance: none;
+        text-align: inherit;
 
         @apply(--paper-font-subhead);
         @apply(--paper-input-container-input);
@@ -254,6 +271,10 @@
         resize: none;
       }
 
+      .add-on-content {
+        position: relative;
+      }
+
       .add-on-content.is-invalid ::content * {
         color: var(--paper-input-container-invalid-color, --google-red-500);
       }
@@ -269,7 +290,8 @@
 
     <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]">
       <content select="[prefix]" id="prefix"></content>
-      <div class="label-and-input-container">
+
+      <div class="label-and-input-container" id="labelAndInputContainer">
         <content select=":not([add-on]):not([prefix]):not([suffix])"></content>
       </div>
       <content select="[suffix]"></content>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-error.html b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-error.html
index f8454eb..057fdb3 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-error.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input-error.html
@@ -41,6 +41,8 @@
         @apply(--paper-font-caption);
         @apply(--paper-input-error);
         position: absolute;
+        left:0;
+        right:0;
       }
 
       :host([invalid]) {
@@ -49,7 +51,7 @@
     </style>
 
     <content></content>
-    
+
   </template>
 </dom-module>
 
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input.html b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input.html
index d168374..8836117 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/paper-input.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/paper-input.html
@@ -15,6 +15,8 @@
 <link rel="import" href="paper-input-char-counter.html">
 
 <!--
+Material design: [Text fields](https://www.google.com/design/spec/components/text-fields.html)
+
 `<paper-input>` is a single-line text field with Material Design styling.
 
     <paper-input label="Input label"></paper-input>
@@ -34,9 +36,10 @@
       <paper-icon-button suffix icon="clear"></paper-icon-button>
     </paper-input>
 
-A `paper-input` can use the native `type=search` features. However, since
-we can't control the native styling of the input, it's recommended to use
-a placeholder text, or `always-float-label`, as to not overlap the native search icon.
+A `paper-input` can use the native `type=search` or `type=file` features.
+However, since we can't control the native styling of the input, in these cases
+it's recommended to use a placeholder text, or `always-float-label`,
+as to not overlap the native UI (search icon, file button, etc.).
 
     <paper-input label="search!" type="search"
         placeholder="search for cats" autosave="test" results="5">
@@ -86,7 +89,7 @@
 
       <label hidden$="[[!label]]">[[label]]</label>
 
-      <input is="iron-input" id="input" aria-labelledby$="[[_ariaLabelledBy]]" aria-describedby$="[[_ariaDescribedBy]]" disabled$="[[disabled]]" bind-value="{{value}}" invalid="{{invalid}}" prevent-invalid-input="[[preventInvalidInput]]" allowed-pattern="[[allowedPattern]]" validator="[[validator]]" type$="[[type]]" pattern$="[[pattern]]" required$="[[required]]" autocomplete$="[[autocomplete]]" autofocus$="[[autofocus]]" inputmode$="[[inputmode]]" minlength$="[[minlength]]" maxlength$="[[maxlength]]" min$="[[min]]" max$="[[max]]" step$="[[step]]" name$="[[name]]" placeholder$="[[placeholder]]" readonly$="[[readonly]]" list$="[[list]]" size$="[[size]]" autocapitalize$="[[autocapitalize]]" autocorrect$="[[autocorrect]]" on-change="_onChange" autosave$="[[autosave]]" ,="" results$="[[results]]">
+      <input is="iron-input" id="input" aria-labelledby$="[[_ariaLabelledBy]]" aria-describedby$="[[_ariaDescribedBy]]" disabled$="[[disabled]]" bind-value="{{value}}" invalid="{{invalid}}" prevent-invalid-input="[[preventInvalidInput]]" allowed-pattern="[[allowedPattern]]" validator="[[validator]]" type$="[[type]]" pattern$="[[pattern]]" required$="[[required]]" autocomplete$="[[autocomplete]]" autofocus$="[[autofocus]]" inputmode$="[[inputmode]]" minlength$="[[minlength]]" maxlength$="[[maxlength]]" min$="[[min]]" max$="[[max]]" step$="[[step]]" name$="[[name]]" placeholder$="[[placeholder]]" readonly$="[[readonly]]" list$="[[list]]" size$="[[size]]" autocapitalize$="[[autocapitalize]]" autocorrect$="[[autocorrect]]" on-change="_onChange" autosave$="[[autosave]]" results$="[[results]]" accept$="[[accept]]" multiple$="[[multiple]]">
 
       <content select="[suffix]"></content>
 
diff --git a/third_party/polymer/v1_0/components-chromium/paper-input/paper-textarea.html b/third_party/polymer/v1_0/components-chromium/paper-input/paper-textarea.html
index 8f68c07..22295743 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-input/paper-textarea.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-input/paper-textarea.html
@@ -42,7 +42,7 @@
 
       <label hidden$="[[!label]]">[[label]]</label>
 
-      <iron-autogrow-textarea id="input" class="paper-input-input" bind-value="{{value}}" autocomplete$="[[autocomplete]]" autofocus$="[[autofocus]]" inputmode$="[[inputmode]]" name$="[[name]]" placeholder$="[[placeholder]]" readonly$="[[readonly]]" required$="[[required]]" maxlength$="[[maxlength]]" autocapitalize$="[[autocapitalize]]" rows$="[[rows]]" max-rows$="[[maxRows]]" on-change="_onChange"></iron-autogrow-textarea>
+      <iron-autogrow-textarea id="input" class="paper-input-input" bind-value="{{value}}" disabled$="[[disabled]]" autocomplete$="[[autocomplete]]" autofocus$="[[autofocus]]" inputmode$="[[inputmode]]" name$="[[name]]" placeholder$="[[placeholder]]" readonly$="[[readonly]]" required$="[[required]]" maxlength$="[[maxlength]]" autocapitalize$="[[autocapitalize]]" rows$="[[rows]]" max-rows$="[[maxRows]]" on-change="_onChange"></iron-autogrow-textarea>
 
       <template is="dom-if" if="[[errorMessage]]">
         <paper-input-error>[[errorMessage]]</paper-input-error>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-item/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-item/.bower.json
index 79b6b234..657aa463 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-item/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-item/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-item",
-  "version": "1.0.5",
+  "version": "1.0.6",
   "description": "A material-design styled list item",
   "authors": [
     "The Polymer Authors"
@@ -39,11 +39,11 @@
     "web-component-tester": "Polymer/web-component-tester#^3.3.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.5",
+  "_release": "1.0.6",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.5",
-    "commit": "a292fb913d0e9f1e7b9bb46d2af60dc8c7a05dc3"
+    "tag": "v1.0.6",
+    "commit": "803078d9942d1279fb6f4142b7522186d57f17c8"
   },
   "_source": "git://github.com/PolymerElements/paper-item.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-item/.travis.yml b/third_party/polymer/v1_0/components-chromium/paper-item/.travis.yml
new file mode 100644
index 0000000..8be788d8
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-item/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: NCk3KK+wbaXMzp8XAY6FeL+TSdI0AlPI3/tl0OpsUIaU2EiCjQuzf/UpyzCW5XZMEVFF4q/eDjrPkqJodHfpngj36mpkfmfqj9DrgDmYsV9BDvsTd8KmLsA6H8D6p7Qer+r1JMMB8PvX44vdhQ6GhZD1HFNYK1Ekpt0TkYwWKNw=
+  - secure: TGgUEQe6FJS+GuYk94d//8YQmDLUu0ekMvPSIs8TQ2QkdBK4SL+2bSXZt44BbDEOwc9P4NCPSUx/RMiCAqsc5OGRJImzb/zqPNIDTeKG6q72HPBBBD3Sk0CrEpTQbOK/Flaa/B7RYR0U1kuljSmRS7lPG19nnY8gOHnIAgwIyk0=
diff --git a/third_party/polymer/v1_0/components-chromium/paper-item/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/paper-item/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-item/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/paper-item/README.md b/third_party/polymer/v1_0/components-chromium/paper-item/README.md
index 02f82024..95cd919 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-item/README.md
+++ b/third_party/polymer/v1_0/components-chromium/paper-item/README.md
@@ -1,4 +1,125 @@
-paper-item
-=========
 
-A non-interactive list item.
+<!---
+
+This README is automatically generated from the comments in these files:
+all-imports.html  paper-icon-item.html  paper-item-body.html  paper-item-shared-styles.html  paper-item.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/paper-item)_
+
+
+##&lt;paper-item&gt;
+
+
+Material design: [Lists](https://www.google.com/design/spec/components/lists.html)
+
+`<paper-item>` is a non-interactive list item. By default, it is a horizontal flexbox.
+
+    <paper-item>Item</paper-item>
+
+Use this element with `<paper-item-body>` to make Material Design styled two-line and three-line
+items.
+
+    <paper-item>
+      <paper-item-body two-line>
+        <div>Show your status</div>
+        <div secondary>Your status is visible to everyone</div>
+      </paper-item-body>
+      <iron-icon icon="warning"></iron-icon>
+    </paper-item>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property               | Description                                    | Default
+------------------------------|------------------------------------------------|----------
+`--paper-item-min-height`     | Minimum height of the item                     | `48px`
+`--paper-item`                | Mixin applied to the item                      | `{}`
+`--paper-item-selected-weight`| The font weight of a selected item             | `bold`
+`--paper-item-selected`       | Mixin applied to selected paper-items                | `{}`
+`--paper-item-disabled-color` | The color for disabled paper-items             | `--disabled-text-color`
+`--paper-item-disabled`       | Mixin applied to disabled paper-items        | `{}`
+`--paper-item-focused`        | Mixin applied to focused paper-items         | `{}`
+`--paper-item-focused-before` | Mixin applied to :before focused paper-items | `{}`
+
+
+### Accessibility
+
+This element has `role="listitem"` by default. Depending on usage, it may be more appropriate to set
+`role="menuitem"`, `role="menuitemcheckbox"` or `role="menuitemradio"`.
+
+    <paper-item role="menuitemcheckbox">
+      <paper-item-body>
+        Show your status
+      </paper-item-body>
+      <paper-checkbox></paper-checkbox>
+    </paper-item>
+
+
+
+##&lt;paper-icon-item&gt;
+
+
+`<paper-icon-item>` is a convenience element to make an item with icon. It is a non interactive list
+item with a fixed-width icon area, according to Material Design. This is useful if the icons are of
+varying widths, but you want the item bodies to line up. Use this like a `<paper-item>`. The child
+node with the attribute `item-icon` is placed in the icon area.
+
+    <paper-icon-item>
+      <iron-icon icon="favorite" item-icon></iron-icon>
+      Favorite
+    </paper-icon-item>
+    <paper-icon-item>
+      <div class="avatar" item-icon></div>
+      Avatar
+    </paper-icon-item>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property               | Description                                    | Default
+------------------------------|------------------------------------------------|----------
+`--paper-item-icon-width`     | Width of the icon area                         | `56px`
+`--paper-icon-item`           | Mixin applied to the item                      | `{}`
+`--paper-item-selected-weight`| The font weight of a selected item             | `bold`
+`--paper-item-selected`       | Mixin applied to selected paper-items                | `{}`
+`--paper-item-disabled-color` | The color for disabled paper-items             | `--disabled-text-color`
+`--paper-item-disabled`       | Mixin applied to disabled paper-items        | `{}`
+`--paper-item-focused`        | Mixin applied to focused paper-items         | `{}`
+`--paper-item-focused-before` | Mixin applied to :before focused paper-items | `{}`
+
+
+
+##&lt;paper-item-body&gt;
+
+
+Use `<paper-item-body>` in a `<paper-item>` or `<paper-icon-item>` to make two- or
+three- line items. It is a flex item that is a vertical flexbox.
+
+    <paper-item>
+      <paper-item-body two-line>
+        <div>Show your status</div>
+        <div secondary>Your status is visible to everyone</div>
+      </paper-item-body>
+    </paper-item>
+
+The child elements with the `secondary` attribute is given secondary text styling.
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-item-body-two-line-min-height`   | Minimum height of a two-line item          | `72px`
+`--paper-item-body-three-line-min-height` | Minimum height of a three-line item        | `88px`
+`--paper-item-body-secondary-color`       | Foreground color for the `secondary` area  | `--secondary-text-color`
+`--paper-item-body-secondary`             | Mixin applied to the `secondary` area      | `{}`
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/paper-item/bower.json b/third_party/polymer/v1_0/components-chromium/paper-item/bower.json
index 5d6c89b..57850c68 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-item/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-item/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-item",
-  "version": "1.0.5",
+  "version": "1.0.6",
   "description": "A material-design styled list item",
   "authors": [
     "The Polymer Authors"
diff --git a/third_party/polymer/v1_0/components-chromium/paper-item/paper-icon-item-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-item/paper-icon-item-extracted.js
index 00cb1d3..6b5eb2a 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-item/paper-icon-item-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-item/paper-icon-item-extracted.js
@@ -2,7 +2,7 @@
       is: 'paper-icon-item',
 
       hostAttributes: {
-        'role': 'listitem',
+        'role': 'option',
         'tabindex': '0'
       },
 
diff --git a/third_party/polymer/v1_0/components-chromium/paper-item/paper-item-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-item/paper-item-extracted.js
index f115b48..e554a24 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-item/paper-item-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-item/paper-item-extracted.js
@@ -2,7 +2,7 @@
       is: 'paper-item',
 
       hostAttributes: {
-        role: 'listitem',
+        role: 'option',
         tabindex: '0'
       },
 
diff --git a/third_party/polymer/v1_0/components-chromium/paper-material/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-material/.bower.json
index f55c38e..0474530 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-material/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-material/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-material",
-  "version": "1.0.2",
+  "version": "1.0.3",
   "description": "A material design container that looks like a lifted sheet of paper",
   "private": true,
   "authors": [
@@ -24,20 +24,20 @@
   "homepage": "https://github.com/PolymerElements/paper-material",
   "ignore": [],
   "dependencies": {
-    "paper-styles": "polymerelements/paper-styles#^1.0.0",
-    "polymer": "Polymer/polymer#^1.0.0"
+    "polymer": "Polymer/polymer#^1.1.0",
+    "paper-styles": "polymerelements/paper-styles#^1.0.0"
   },
   "devDependencies": {
-    "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
-    "test-fixture": "polymerelements/test-fixture#^1.0.0",
+    "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
     "web-component-tester": "*",
-    "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+    "test-fixture": "polymerelements/test-fixture#^1.0.0",
+    "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
   },
-  "_release": "1.0.2",
+  "_release": "1.0.3",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.2",
-    "commit": "3f41d6dd776cf5bb35d29b44d1cce4981b791188"
+    "tag": "v1.0.3",
+    "commit": "2e99c0754edb817518f59313d2533ccc2e1ab82a"
   },
   "_source": "git://github.com/PolymerElements/paper-material.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-material/bower.json b/third_party/polymer/v1_0/components-chromium/paper-material/bower.json
index f1051fc..42d0c186 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-material/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-material/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-material",
-  "version": "1.0.2",
+  "version": "1.0.3",
   "description": "A material design container that looks like a lifted sheet of paper",
   "private": true,
   "authors": [
@@ -24,13 +24,13 @@
   "homepage": "https://github.com/PolymerElements/paper-material",
   "ignore": [],
   "dependencies": {
-    "paper-styles": "polymerelements/paper-styles#^1.0.0",
-    "polymer": "Polymer/polymer#^1.0.0"
+    "polymer": "Polymer/polymer#^1.1.0",
+    "paper-styles": "polymerelements/paper-styles#^1.0.0"
   },
   "devDependencies": {
-    "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
-    "test-fixture": "polymerelements/test-fixture#^1.0.0",
+    "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
     "web-component-tester": "*",
-    "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+    "test-fixture": "polymerelements/test-fixture#^1.0.0",
+    "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
   }
 }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-material/paper-material-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-material/paper-material-extracted.js
index caf5f9d..733f980 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-material/paper-material-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-material/paper-material-extracted.js
@@ -2,7 +2,6 @@
     is: 'paper-material',
 
     properties: {
-
       /**
        * The z-depth of this element, from 0-5. Setting to 0 will remove the
        * shadow, and each increasing number greater than 0 will be "deeper"
diff --git a/third_party/polymer/v1_0/components-chromium/paper-material/paper-material.html b/third_party/polymer/v1_0/components-chromium/paper-material/paper-material.html
index e42a256..4bb3e4d6 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-material/paper-material.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-material/paper-material.html
@@ -10,6 +10,7 @@
 <link rel="import" href="../paper-styles/shadow.html">
 
 <!--
+Material design: [Cards](https://www.google.com/design/spec/components/cards.html)
 
 `paper-material` is a container that renders two shadows on top of each other to
 create the effect of a lifted piece of paper.
@@ -21,42 +22,42 @@
     </paper-material>
 
 @group Paper Elements
-@class paper-material
 @demo demo/index.html
 -->
 
 </head><body><dom-module id="paper-material">
-  <style>
-    :host {
-      display: block;
-      position: relative;
-    }
-
-    :host([animated]) {
-      @apply(--shadow-transition);
-    }
-
-    :host([elevation="1"]) {
-      @apply(--shadow-elevation-2dp);
-    }
-
-    :host([elevation="2"]) {
-      @apply(--shadow-elevation-4dp);
-    }
-
-    :host([elevation="3"]) {
-      @apply(--shadow-elevation-6dp);
-    }
-
-    :host([elevation="4"]) {
-      @apply(--shadow-elevation-8dp);
-    }
-
-    :host([elevation="5"]) {
-      @apply(--shadow-elevation-16dp);
-    }
-  </style>
   <template>
+    <style>
+      :host {
+        display: block;
+        position: relative;
+      }
+
+      :host([animated]) {
+        @apply(--shadow-transition);
+      }
+
+      :host([elevation="1"]) {
+        @apply(--shadow-elevation-2dp);
+      }
+
+      :host([elevation="2"]) {
+        @apply(--shadow-elevation-4dp);
+      }
+
+      :host([elevation="3"]) {
+        @apply(--shadow-elevation-6dp);
+      }
+
+      :host([elevation="4"]) {
+        @apply(--shadow-elevation-8dp);
+      }
+
+      :host([elevation="5"]) {
+        @apply(--shadow-elevation-16dp);
+      }
+    </style>
+
     <content></content>
   </template>
 </dom-module>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-button/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-radio-button/.bower.json
index 68b7235..bfb04c1 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-radio-button/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-button/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-radio-button",
-  "version": "1.0.9",
+  "version": "1.0.11",
   "description": "A material design radio button",
   "authors": [
     "The Polymer Authors"
@@ -20,24 +20,25 @@
   "homepage": "https://github.com/PolymerElements/paper-radio-button",
   "ignore": [],
   "dependencies": {
-    "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
-    "paper-styles": "PolymerLabs/paper-styles#^1.0.0",
-    "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
     "iron-checked-element-behavior": "PolymerElements/iron-checked-element-behavior#^1.0.0",
+    "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+    "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+    "paper-styles": "PolymerElements/paper-styles#^1.0.0",
     "polymer": "Polymer/polymer#^1.1.0"
   },
   "devDependencies": {
-    "web-component-tester": "Polymer/web-component-tester#^3.3.0",
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
-    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
     "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+    "web-component-tester": "Polymer/web-component-tester#^3.3.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.9",
+  "main": "paper-radio-button.html",
+  "_release": "1.0.11",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.9",
-    "commit": "708d1e611ad5a7c9600a128545a88e9991fe789e"
+    "tag": "v1.0.11",
+    "commit": "5ba3cec1efcbdb0df3e5df28930473ea02539845"
   },
   "_source": "git://github.com/PolymerElements/paper-radio-button.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-button/.travis.yml b/third_party/polymer/v1_0/components-chromium/paper-radio-button/.travis.yml
new file mode 100644
index 0000000..6b091474
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-button/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: P6B/39IMzhm/jBmxD+0CDZEPYNMMaizAgpn4MXUUlAmmdMJNwovzvm/kYtVyoPfGiJ08NJh5tNRLQbkG12OH71lQ7ReTiru0hEy93ssmIh0U6ZUAAxTZVQ9SxB5gjrQU8/0fVJ9tNd0kBklHH4FoK+ZtJurhKLJaXhXsupXpcuI=
+  - secure: rxY6LCY199Lt1aRGK8Hpq3wjx8xcpb91x21fJStKROlpJTlfp+c0yevK1oYkklzChJWEFewFNTYlHbm9pc7TCyXK2WCR0v1GgSeJAUpP4TONkdpueeOvsVC/CGB9mIXEtfUEh2CCdWDj+D7JGLdUvbgmu8C3gfqfP+AyXbQt5Jc=
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-button/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/paper-radio-button/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-button/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-button/README.md b/third_party/polymer/v1_0/components-chromium/paper-radio-button/README.md
index eee7af6..e3c1a986 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-radio-button/README.md
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-button/README.md
@@ -1,4 +1,23 @@
-# paper-radio-button
+
+<!---
+
+This README is automatically generated from the comments in these files:
+paper-radio-button.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/paper-radio-button.svg?branch=master)](https://travis-ci.org/PolymerElements/paper-radio-button)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/paper-radio-button)_
+
+
+##&lt;paper-radio-button&gt;
+
+
+Material design: [Radio button](https://www.google.com/design/spec/components/selection-controls.html#selection-controls-radio-button)
 
 `paper-radio-button` is a button that can be either checked or unchecked.
 User can tap the radio button to check or uncheck it.
@@ -6,27 +25,24 @@
 Use a `<paper-radio-group>` to group a set of radio buttons.  When radio buttons
 are inside a radio group, exactly one radio button in the group can be checked
 at any time.
+
 Example:
 
-```html
-<paper-radio-button></paper-radio-button>
-<paper-radio-button>Item label</paper-radio-button>
-```
-Styling a radio button:
+    <paper-radio-button></paper-radio-button>
+    <paper-radio-button>Item label</paper-radio-button>
 
-```html
-<style is="custom-style">
-  :root {
-    /* Unchecked state colors. */
-    --paper-radio-button-unchecked-color: #5a5a5a;
-    --paper-radio-button-unchecked-background-color: #fff;
-    --paper-radio-button-unchecked-ink-color: #5a5a5a;
+### Styling
 
-    /* Checked state colors. */
-    --paper-radio-button-checked-color: #009688;
-    --paper-radio-button-checked-ink-color: #0f9d58;
+The following custom properties and mixins are available for styling:
 
-    --paper-radio-button-label-color: black;
-  }
-</style>
-```
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-radio-button-unchecked-background-color` | Radio button background color when the input is not checked | `transparent`
+`--paper-radio-button-unchecked-color` | Radio button color when the input is not checked | `--primary-text-color`
+`--paper-radio-button-unchecked-ink-color` | Selected/focus ripple color when the input is not checked | `--primary-text-color`
+`--paper-radio-button-checked-color` | Radio button color when the input is checked | `--default-primary-color`
+`--paper-radio-button-checked-ink-color` | Selected/focus ripple color when the input is checked | `--default-primary-color`
+`--paper-radio-button-label-color` | Label color | `--primary-text-color`
+`--paper-radio-button-label-spacing` | Spacing between the label and the button | `10px`
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-button/bower.json b/third_party/polymer/v1_0/components-chromium/paper-radio-button/bower.json
index 2069abe..f40c0ec6 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-radio-button/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-button/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-radio-button",
-  "version": "1.0.9",
+  "version": "1.0.11",
   "description": "A material design radio button",
   "authors": [
     "The Polymer Authors"
@@ -20,17 +20,18 @@
   "homepage": "https://github.com/PolymerElements/paper-radio-button",
   "ignore": [],
   "dependencies": {
-    "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
-    "paper-styles": "PolymerLabs/paper-styles#^1.0.0",
-    "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
     "iron-checked-element-behavior": "PolymerElements/iron-checked-element-behavior#^1.0.0",
+    "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+    "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+    "paper-styles": "PolymerElements/paper-styles#^1.0.0",
     "polymer": "Polymer/polymer#^1.1.0"
   },
   "devDependencies": {
-    "web-component-tester": "Polymer/web-component-tester#^3.3.0",
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
-    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
     "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+    "web-component-tester": "Polymer/web-component-tester#^3.3.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
-  }
+  },
+  "main": "paper-radio-button.html"
 }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-button/paper-radio-button.html b/third_party/polymer/v1_0/components-chromium/paper-radio-button/paper-radio-button.html
index f60ce27b..60e949d 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-radio-button/paper-radio-button.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-button/paper-radio-button.html
@@ -7,9 +7,9 @@
 Code distributed by Google as part of the polymer project is also
 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 --><html><head><link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-behaviors/paper-checked-element-behavior.html">
 <link rel="import" href="../paper-ripple/paper-ripple.html">
 <link rel="import" href="../paper-styles/default-theme.html">
-<link rel="import" href="../paper-behaviors/paper-checked-element-behavior.html">
 
 <!--
 Material design: [Radio button](https://www.google.com/design/spec/components/selection-controls.html#selection-controls-radio-button)
@@ -38,6 +38,7 @@
 `--paper-radio-button-checked-color` | Radio button color when the input is checked | `--default-primary-color`
 `--paper-radio-button-checked-ink-color` | Selected/focus ripple color when the input is checked | `--default-primary-color`
 `--paper-radio-button-label-color` | Label color | `--primary-text-color`
+`--paper-radio-button-label-spacing` | Spacing between the label and the button | `10px`
 
 @group Paper Elements
 @element paper-radio-button
@@ -51,6 +52,7 @@
       :host {
         display: inline-block;
         white-space: nowrap;
+        cursor: pointer;
       }
 
       :host(:focus) {
@@ -62,11 +64,10 @@
         position: relative;
         width: 16px;
         height: 16px;
-        cursor: pointer;
         vertical-align: middle;
       }
 
-      :host #ink {
+      #ink {
         position: absolute;
         top: -16px;
         left: -16px;
@@ -77,15 +78,21 @@
         pointer-events: none;
       }
 
-      :host #ink[checked] {
+      :host-context([dir="rtl"]) #ink {
+        right: -15px;
+        left: auto;
+      }
+
+      #ink[checked] {
         color: var(--paper-radio-button-checked-ink-color, --default-primary-color);
       }
 
-      :host #offRadio {
+      #offRadio {
         position: absolute;
         box-sizing: content-box;
         top: 0px;
         left: 0px;
+        right: 0px;
         width: 12px;
         height: 12px;
         border-radius: 50%;
@@ -95,11 +102,12 @@
         transition: border-color 0.28s;
       }
 
-      :host #onRadio {
+      #onRadio {
         position: absolute;
         box-sizing: content-box;
         top: 4px;
         left: 4px;
+        right: 4px;
         width: 8px;
         height: 8px;
         border-radius: 50%;
@@ -123,12 +131,17 @@
         position: relative;
         display: inline-block;
         vertical-align: middle;
-        margin-left: 10px;
+        margin-left: var(--paper-radio-button-label-spacing, 10px);
         white-space: normal;
         pointer-events: none;
         color: var(--paper-radio-button-label-color, --primary-text-color);
       }
 
+      :host-context([dir="rtl"]) #radioLabel {
+        margin-left: 0px;
+        margin-right: var(--paper-radio-button-label-spacing, 10px);
+      }
+
       #radioLabel[hidden] {
         display: none;
       }
@@ -160,7 +173,6 @@
     </div>
 
     <div id="radioLabel"><content></content></div>
-
   </template>
 
   </dom-module>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-group/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-radio-group/.bower.json
index 23e7a3f..6933999 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-radio-group/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-group/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-radio-group",
-  "version": "1.0.5",
+  "version": "1.0.6",
   "description": "A group of material design radio buttons",
   "authors": [
     "The Polymer Authors"
@@ -14,30 +14,30 @@
   "private": true,
   "repository": {
     "type": "git",
-    "url": "git://github.com/PolymerElements/paper-radio-group"
+    "url": "git://github.com/PolymerElements/paper-radio-group.git"
   },
   "license": "http://polymer.github.io/LICENSE.txt",
   "homepage": "https://github.com/PolymerElements/paper-radio-group",
   "ignore": [],
   "dependencies": {
-    "iron-selector": "PolymerElements/iron-selector#^1.0.0",
     "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
+    "iron-selector": "PolymerElements/iron-selector#^1.0.0",
     "polymer": "Polymer/polymer#^1.0.0"
   },
   "devDependencies": {
-    "web-component-tester": "*",
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
-    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+    "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
     "paper-radio-button": "PolymerElements/paper-radio-button#^1.0.0",
     "paper-styles": "PolymerElements/paper-styles#^1.0.0",
-    "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+    "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.5",
+  "_release": "1.0.6",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.5",
-    "commit": "cab4056c58d273f0953c70cc070001c97c9950b3"
+    "tag": "v1.0.6",
+    "commit": "e52738e71ebb7ec5470de109f4aa7b419f6f72e5"
   },
   "_source": "git://github.com/PolymerElements/paper-radio-group.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-group/bower.json b/third_party/polymer/v1_0/components-chromium/paper-radio-group/bower.json
index 8ced8c7..4b65113 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-radio-group/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-group/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-radio-group",
-  "version": "1.0.5",
+  "version": "1.0.6",
   "description": "A group of material design radio buttons",
   "authors": [
     "The Polymer Authors"
@@ -14,23 +14,23 @@
   "private": true,
   "repository": {
     "type": "git",
-    "url": "git://github.com/PolymerElements/paper-radio-group"
+    "url": "git://github.com/PolymerElements/paper-radio-group.git"
   },
   "license": "http://polymer.github.io/LICENSE.txt",
   "homepage": "https://github.com/PolymerElements/paper-radio-group",
   "ignore": [],
   "dependencies": {
-    "iron-selector": "PolymerElements/iron-selector#^1.0.0",
     "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
+    "iron-selector": "PolymerElements/iron-selector#^1.0.0",
     "polymer": "Polymer/polymer#^1.0.0"
   },
   "devDependencies": {
-    "web-component-tester": "*",
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
-    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+    "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
     "paper-radio-button": "PolymerElements/paper-radio-button#^1.0.0",
     "paper-styles": "PolymerElements/paper-styles#^1.0.0",
-    "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+    "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+    "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   }
 }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-radio-group/paper-radio-group.html b/third_party/polymer/v1_0/components-chromium/paper-radio-group/paper-radio-group.html
index 9e5f9ea..ea384e9 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-radio-group/paper-radio-group.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-radio-group/paper-radio-group.html
@@ -7,9 +7,9 @@
 Code distributed by Google as part of the polymer project is also
 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 --><html><head><link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
 <link rel="import" href="../iron-selector/iron-selectable.html">
 <link rel="import" href="../paper-radio-button/paper-radio-button.html">
-<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
 
 <!--
 Material design: [Radio button](https://www.google.com/design/spec/components/selection-controls.html#selection-controls-radio-button)
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-spinner/.bower.json
index 9d2afae..87f380d 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-spinner/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-spinner",
-  "version": "1.0.2",
+  "version": "1.0.4",
   "description": "A material design spinner",
   "authors": [
     "The Polymer Authors"
@@ -22,19 +22,20 @@
   "dependencies": {
     "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
     "paper-styles": "PolymerElements/paper-styles#^1.0.0",
-    "polymer": "Polymer/polymer#^1.0.0"
+    "polymer": "Polymer/polymer#^1.1.0"
   },
   "devDependencies": {
-    "web-component-tester": "*",
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
     "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+    "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
   },
-  "_release": "1.0.2",
+  "main": "paper-spinner.html",
+  "_release": "1.0.4",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.2",
-    "commit": "18bda194750ace719102d54c17ae1c6ce4a6793e"
+    "tag": "v1.0.4",
+    "commit": "731e067cada82c724df9bd676dfd7324699e4793"
   },
   "_source": "git://github.com/PolymerElements/paper-spinner.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/.travis.yml b/third_party/polymer/v1_0/components-chromium/paper-spinner/.travis.yml
new file mode 100644
index 0000000..f12cf79
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: dpHtK5BMl68o/D6cQO9VsQWBPVuTrFPC56NT6kBLbiQtmxG2E2FD8dN4cHuEWafZopwYSsLLmEIIK77FMaonTSmzos5EixIQyqGxWTyNTpthg0Jenzc+6vZEs3h+3LDodFjdZSu8FgKyxU8SFLLGjAsSy8aegUNBszy7/SY8FAM=
+  - secure: EASvFsWb/njjh3DOLD5Oz3nw4QPl4aIhDAIhU2qelb2UCp8Q/KGniU7VjNoQ7OSN05jh2ooz8Pu3cAhLmrWumJn2atXEXvRPKtT/+1Ciy3xFcvgmqM0RHB+7qSSOUwgvPW9bwdzVxxMjAW7Oqb7w3nVn9/mEv2sMPNSv7iEbiUI=
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/paper-spinner/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/README.md b/third_party/polymer/v1_0/components-chromium/paper-spinner/README.md
index c447c8b..82d6ff0 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-spinner/README.md
+++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/README.md
@@ -1,45 +1,50 @@
-paper-spinner
-=============
+
+<!---
+
+This README is automatically generated from the comments in these files:
+paper-spinner.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/paper-spinner.svg?branch=master)](https://travis-ci.org/PolymerElements/paper-spinner)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/paper-spinner)_
+
+
+##&lt;paper-spinner&gt;
+
+
+Material design: [Progress & activity](https://www.google.com/design/spec/components/progress-activity.html)
 
 Element providing material design circular spinner.
 
-##### Example
-
-```html
-<paper-spinner active></paper-spinner>
-```
+    <paper-spinner active></paper-spinner>
 
 The default spinner cycles between four layers of colors; by default they are
 blue, red, yellow and green. It can be customized so that it uses one color only
 by setting all the layer colors to the same value.
 
-##### Example
-
-```html
-<style is="custom-style">
-  paper-spinner .rainbow {
-    --paper-spinner-layer-1-color: yellow;
-    --paper-spinner-layer-2-color: red;
-    --paper-spinner-layer-3-color: blue;
-    --paper-spinner-layer-4-color: green;
-  }
-
-  paper-spinner .red {
-    --paper-spinner-layer-1-color: red;
-    --paper-spinner-layer-2-color: red;
-    --paper-spinner-layer-3-color: red;
-    --paper-spinner-layer-4-color: red;
-  }
-</style>
-```
+### Accessibility
 
 Alt attribute should be set to provide adequate context for accessibility. If not provided,
 it defaults to 'loading'.
 Empty alt can be provided to mark the element as decorative if alternative content is provided
 in another form (e.g. a text block following the spinner).
 
-##### Example
+    <paper-spinner alt="Loading contacts list" active></paper-spinner>
 
-```html
-<paper-spinner alt="Loading contacts list" active></paper-spinner>
-```
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-spinner-layer-1-color` | Color of the first spinner rotation | `--google-blue-500`
+`--paper-spinner-layer-2-color` | Color of the second spinner rotation | `--google-red-500`
+`--paper-spinner-layer-3-color` | Color of the third spinner rotation | `--google-yellow-500`
+`--paper-spinner-layer-4-color` | Color of the fourth spinner rotation | `--google-green-500`
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/bower.json b/third_party/polymer/v1_0/components-chromium/paper-spinner/bower.json
index a8c31cf..305d0bb 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-spinner/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-spinner",
-  "version": "1.0.2",
+  "version": "1.0.4",
   "description": "A material design spinner",
   "authors": [
     "The Polymer Authors"
@@ -22,12 +22,13 @@
   "dependencies": {
     "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
     "paper-styles": "PolymerElements/paper-styles#^1.0.0",
-    "polymer": "Polymer/polymer#^1.0.0"
+    "polymer": "Polymer/polymer#^1.1.0"
   },
   "devDependencies": {
-    "web-component-tester": "*",
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
     "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+    "web-component-tester": "*",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
-  }
+  },
+  "main": "paper-spinner.html"
 }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-extracted.js
index 27043f8..1cfb3cb 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-extracted.js
@@ -1,5 +1,4 @@
 Polymer({
-
       is: 'paper-spinner',
 
       listeners: {
@@ -8,7 +7,6 @@
       },
 
       properties: {
-
         /**
          * Displays the spinner.
          *
@@ -51,7 +49,6 @@
           type: String,
           computed: '_computeSpinnerContainerClassName(active, _coolingDown)'
         }
-
       },
 
       _computeSpinnerContainerClassName: function(active, coolingDown) {
@@ -63,9 +60,7 @@
 
       _activeChanged: function(active, old) {
         this._setAriaHidden(!active);
-        if (!active && old) {
-          this._coolingDown = true;
-        }
+        this._coolingDown = !active && old;
       },
 
       _altChanged: function(alt) {
@@ -91,5 +86,4 @@
         this.active = false;
         this._coolingDown = false;
       }
-
     });
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-styles.html b/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-styles.html
new file mode 100644
index 0000000..50dde61
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-styles.html
@@ -0,0 +1,338 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<dom-module id="paper-spinner-styles">
+  <template>
+    <style>
+      /*
+      /**************************/
+      /* STYLES FOR THE SPINNER */
+      /**************************/
+
+      /*
+       * Constants:
+       *      STROKEWIDTH = 3px
+       *      ARCSIZE     = 270 degrees (amount of circle the arc takes up)
+       *      ARCTIME     = 1333ms (time it takes to expand and contract arc)
+       *      ARCSTARTROT = 216 degrees (how much the start location of the arc
+       *                                should rotate each time, 216 gives us a
+       *                                5 pointed star shape (it's 360/5 * 3).
+       *                                For a 7 pointed star, we might do
+       *                                360/7 * 3 = 154.286)
+       *      CONTAINERWIDTH = 28px
+       *      SHRINK_TIME = 400ms
+       */
+
+      :host {
+        display: inline-block;
+        position: relative;
+        width: 28px; /* CONTAINERWIDTH */
+        height: 28px; /* CONTAINERWIDTH */
+      }
+
+      #spinnerContainer {
+        width: 100%;
+        height: 100%;
+
+        /* The spinner does not have any contents that would have to be
+         * flipped if the direction changes. Always use ltr so that the
+         * style works out correctly in both cases. */
+        direction: ltr;
+      }
+
+      #spinnerContainer.active {
+        /* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
+        -webkit-animation: container-rotate 1568ms linear infinite;
+        animation: container-rotate 1568ms linear infinite;
+      }
+
+      @-webkit-keyframes container-rotate {
+        to { -webkit-transform: rotate(360deg) }
+      }
+
+      @keyframes container-rotate {
+        to { transform: rotate(360deg) }
+      }
+
+      .spinner-layer {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        opacity: 0;
+        white-space: nowrap;
+      }
+
+      .layer-1 {
+        border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
+      }
+
+      .layer-2 {
+        border-color: var(--paper-spinner-layer-2-color, --google-red-500);
+      }
+
+      .layer-3 {
+        border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
+      }
+
+      .layer-4 {
+        border-color: var(--paper-spinner-layer-4-color, --google-green-500);
+      }
+
+      /**
+       * IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
+       *
+       * iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
+       * guarantee that the animation will start _exactly_ after that value. So we avoid using
+       * animation-delay and instead set custom keyframes for each color (as layer-2undant as it
+       * seems).
+       *
+       * We write out each animation in full (instead of separating animation-name,
+       * animation-duration, etc.) because under the polyfill, Safari does not recognize those
+       * specific properties properly, treats them as -webkit-animation, and overrides the
+       * other animation rules. See https://github.com/Polymer/platform/issues/53.
+       */
+      .active .spinner-layer.layer-1 {
+        /* durations: 4 * ARCTIME */
+        -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+        animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+      }
+
+      .active .spinner-layer.layer-2 {
+        /* durations: 4 * ARCTIME */
+        -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+        animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+      }
+
+      .active .spinner-layer.layer-3 {
+        /* durations: 4 * ARCTIME */
+        -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+        animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+      }
+
+      .active .spinner-layer.layer-4 {
+        /* durations: 4 * ARCTIME */
+        -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+        animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+      }
+
+      @-webkit-keyframes fill-unfill-rotate {
+        12.5% { -webkit-transform: rotate(135deg);  } /* 0.5 * ARCSIZE */
+        25%   { -webkit-transform: rotate(270deg);  } /* 1   * ARCSIZE */
+        37.5% { -webkit-transform: rotate(405deg);  } /* 1.5 * ARCSIZE */
+        50%   { -webkit-transform: rotate(540deg);  } /* 2   * ARCSIZE */
+        62.5% { -webkit-transform: rotate(675deg);  } /* 2.5 * ARCSIZE */
+        75%   { -webkit-transform: rotate(810deg);  } /* 3   * ARCSIZE */
+        87.5% { -webkit-transform: rotate(945deg);  } /* 3.5 * ARCSIZE */
+        to    { -webkit-transform: rotate(1080deg); } /* 4   * ARCSIZE */
+      }
+
+      @keyframes fill-unfill-rotate {
+        12.5% { transform: rotate(135deg);  } /* 0.5 * ARCSIZE */
+        25%   { transform: rotate(270deg);  } /* 1   * ARCSIZE */
+        37.5% { transform: rotate(405deg);  } /* 1.5 * ARCSIZE */
+        50%   { transform: rotate(540deg);  } /* 2   * ARCSIZE */
+        62.5% { transform: rotate(675deg);  } /* 2.5 * ARCSIZE */
+        75%   { transform: rotate(810deg);  } /* 3   * ARCSIZE */
+        87.5% { transform: rotate(945deg);  } /* 3.5 * ARCSIZE */
+        to    { transform: rotate(1080deg); } /* 4   * ARCSIZE */
+      }
+
+      /**
+       * HACK: Even though the intention is to have the current .spinner-layer at
+       * `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome
+       * to do proper subpixel rendering for the elements being animated. This is
+       * especially visible in Chrome 39 on Ubuntu 14.04. See:
+       *
+       * - https://github.com/Polymer/paper-spinner/issues/9
+       * - https://code.google.com/p/chromium/issues/detail?id=436255
+       */
+      @-webkit-keyframes layer-1-fade-in-out {
+        from { opacity: 0.99; }
+        25% { opacity: 0.99; }
+        26% { opacity: 0; }
+        89% { opacity: 0; }
+        90% { opacity: 0.99; }
+        100% { opacity: 0.99; }
+      }
+
+      @keyframes layer-1-fade-in-out {
+        from { opacity: 0.99; }
+        25% { opacity: 0.99; }
+        26% { opacity: 0; }
+        89% { opacity: 0; }
+        90% { opacity: 0.99; }
+        100% { opacity: 0.99; }
+      }
+
+      @-webkit-keyframes layer-2-fade-in-out {
+        from { opacity: 0; }
+        15% { opacity: 0; }
+        25% { opacity: 0.99; }
+        50% { opacity: 0.99; }
+        51% { opacity: 0; }
+      }
+
+      @keyframes layer-2-fade-in-out {
+        from { opacity: 0; }
+        15% { opacity: 0; }
+        25% { opacity: 0.99; }
+        50% { opacity: 0.99; }
+        51% { opacity: 0; }
+      }
+
+      @-webkit-keyframes layer-3-fade-in-out {
+        from { opacity: 0; }
+        40% { opacity: 0; }
+        50% { opacity: 0.99; }
+        75% { opacity: 0.99; }
+        76% { opacity: 0; }
+      }
+
+      @keyframes layer-3-fade-in-out {
+        from { opacity: 0; }
+        40% { opacity: 0; }
+        50% { opacity: 0.99; }
+        75% { opacity: 0.99; }
+        76% { opacity: 0; }
+      }
+
+      @-webkit-keyframes layer-4-fade-in-out {
+        from { opacity: 0; }
+        65% { opacity: 0; }
+        75% { opacity: 0.99; }
+        90% { opacity: 0.99; }
+        100% { opacity: 0; }
+      }
+
+      @keyframes layer-4-fade-in-out {
+        from { opacity: 0; }
+        65% { opacity: 0; }
+        75% { opacity: 0.99; }
+        90% { opacity: 0.99; }
+        100% { opacity: 0; }
+      }
+
+      /**
+       * Patch the gap that appear between the two adjacent div.circle-clipper while the
+       * spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
+       *
+       * Update: the gap no longer appears on Chrome when .spinner-layer's opacity is 0.99,
+       * but still does on Safari and IE.
+       */
+      .gap-patch {
+        position: absolute;
+        box-sizing: border-box;
+        top: 0;
+        left: 45%;
+        width: 10%;
+        height: 100%;
+        overflow: hidden;
+        border-color: inherit;
+      }
+
+      .gap-patch .circle {
+        width: 1000%;
+        left: -450%;
+      }
+
+      .circle-clipper {
+        display: inline-block;
+        position: relative;
+        width: 50%;
+        height: 100%;
+        overflow: hidden;
+        border-color: inherit;
+      }
+
+      .circle-clipper .circle {
+        width: 200%;
+      }
+
+      .circle {
+        box-sizing: border-box;
+        height: 100%;
+        border-width: 3px; /* STROKEWIDTH */
+        border-style: solid;
+        border-color: inherit;
+        border-bottom-color: transparent !important;
+        border-radius: 50%;
+        -webkit-animation: none;
+        animation: none;
+
+        @apply(--layout-fit);
+      }
+
+      .circle-clipper.left .circle {
+        border-right-color: transparent !important;
+        -webkit-transform: rotate(129deg);
+        transform: rotate(129deg);
+      }
+
+      .circle-clipper.right .circle {
+        left: -100%;
+        border-left-color: transparent !important;
+        -webkit-transform: rotate(-129deg);
+        transform: rotate(-129deg);
+      }
+
+      .active .circle-clipper.left .circle {
+        /* duration: ARCTIME */
+        -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+        animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+      }
+
+      .active .circle-clipper.right .circle {
+        /* duration: ARCTIME */
+        -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+        animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+      }
+
+      @-webkit-keyframes left-spin {
+        from { -webkit-transform: rotate(130deg); }
+        50% { -webkit-transform: rotate(-5deg); }
+        to { -webkit-transform: rotate(130deg); }
+      }
+
+      @keyframes left-spin {
+        from { transform: rotate(130deg); }
+        50% { transform: rotate(-5deg); }
+        to { transform: rotate(130deg); }
+      }
+
+      @-webkit-keyframes right-spin {
+        from { -webkit-transform: rotate(-130deg); }
+        50% { -webkit-transform: rotate(5deg); }
+        to { -webkit-transform: rotate(-130deg); }
+      }
+
+      @keyframes right-spin {
+        from { transform: rotate(-130deg); }
+        50% { transform: rotate(5deg); }
+        to { transform: rotate(-130deg); }
+      }
+
+      #spinnerContainer.cooldown {
+        /* duration: SHRINK_TIME */
+        -webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
+        animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
+      }
+
+      @-webkit-keyframes fade-out {
+        from { opacity: 0.99; }
+        to { opacity: 0; }
+      }
+
+      @keyframes fade-out {
+        from { opacity: 0.99; }
+        to { opacity: 0; }
+      }
+    </style>
+  </template>
+</dom-module>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.css b/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.css
deleted file mode 100644
index d295c3f..0000000
--- a/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.css
+++ /dev/null
@@ -1,330 +0,0 @@
-/**
-@license
-Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
-This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
-The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
-The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
-Code distributed by Google as part of the polymer project is also
-subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-
-*/
-/**************************/
-/* STYLES FOR THE SPINNER */
-/**************************/
-
-/*
- * Constants:
- *      STROKEWIDTH = 3px
- *      ARCSIZE     = 270 degrees (amount of circle the arc takes up)
- *      ARCTIME     = 1333ms (time it takes to expand and contract arc)
- *      ARCSTARTROT = 216 degrees (how much the start location of the arc
- *                                should rotate each time, 216 gives us a
- *                                5 pointed star shape (it's 360/5 * 3).
- *                                For a 7 pointed star, we might do
- *                                360/7 * 3 = 154.286)
- *      CONTAINERWIDTH = 28px
- *      SHRINK_TIME = 400ms
- */
-
-:host {
-  display: inline-block;
-  position: relative;
-  width: 28px; /* CONTAINERWIDTH */
-  height: 28px; /* CONTAINERWIDTH */
-}
-
-#spinnerContainer {
-  width: 100%;
-  height: 100%;
-
-  /* The spinner does not have any contents that would have to be
-   * flipped if the direction changes. Always use ltr so that the
-   * style works out correctly in both cases. */
-  direction: ltr;
-}
-
-#spinnerContainer.active {
-  /* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
-  -webkit-animation: container-rotate 1568ms linear infinite;
-  animation: container-rotate 1568ms linear infinite;
-}
-
-@-webkit-keyframes container-rotate {
-  to { -webkit-transform: rotate(360deg) }
-}
-
-@keyframes container-rotate {
-  to { transform: rotate(360deg) }
-}
-
-.spinner-layer {
-  position: absolute;
-  width: 100%;
-  height: 100%;
-  opacity: 0;
-}
-
-.layer-1 {
-  border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
-}
-
-.layer-2 {
-  border-color: var(--paper-spinner-layer-2-color, --google-red-500);
-}
-
-.layer-3 {
-  border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
-}
-
-.layer-4 {
-  border-color: var(--paper-spinner-layer-4-color, --google-blue-500);
-}
-
-/**
- * IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
- *
- * iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
- * guarantee that the animation will start _exactly_ after that value. So we avoid using
- * animation-delay and instead set custom keyframes for each color (as layer-2undant as it
- * seems).
- *
- * We write out each animation in full (instead of separating animation-name,
- * animation-duration, etc.) because under the polyfill, Safari does not recognize those
- * specific properties properly, treats them as -webkit-animation, and overrides the
- * other animation rules. See https://github.com/Polymer/platform/issues/53.
- */
-.active .spinner-layer.layer-1 {
-  /* durations: 4 * ARCTIME */
-  -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-  animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-}
-
-.active .spinner-layer.layer-2 {
-  /* durations: 4 * ARCTIME */
-  -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-  animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-}
-
-.active .spinner-layer.layer-3 {
-  /* durations: 4 * ARCTIME */
-  -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-  animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-}
-
-.active .spinner-layer.layer-4 {
-  /* durations: 4 * ARCTIME */
-  -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-  animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-}
-
-@-webkit-keyframes fill-unfill-rotate {
-  12.5% { -webkit-transform: rotate(135deg);  } /* 0.5 * ARCSIZE */
-  25%   { -webkit-transform: rotate(270deg);  } /* 1   * ARCSIZE */
-  37.5% { -webkit-transform: rotate(405deg);  } /* 1.5 * ARCSIZE */
-  50%   { -webkit-transform: rotate(540deg);  } /* 2   * ARCSIZE */
-  62.5% { -webkit-transform: rotate(675deg);  } /* 2.5 * ARCSIZE */
-  75%   { -webkit-transform: rotate(810deg);  } /* 3   * ARCSIZE */
-  87.5% { -webkit-transform: rotate(945deg);  } /* 3.5 * ARCSIZE */
-  to    { -webkit-transform: rotate(1080deg); } /* 4   * ARCSIZE */
-}
-
-@keyframes fill-unfill-rotate {
-  12.5% { transform: rotate(135deg);  } /* 0.5 * ARCSIZE */
-  25%   { transform: rotate(270deg);  } /* 1   * ARCSIZE */
-  37.5% { transform: rotate(405deg);  } /* 1.5 * ARCSIZE */
-  50%   { transform: rotate(540deg);  } /* 2   * ARCSIZE */
-  62.5% { transform: rotate(675deg);  } /* 2.5 * ARCSIZE */
-  75%   { transform: rotate(810deg);  } /* 3   * ARCSIZE */
-  87.5% { transform: rotate(945deg);  } /* 3.5 * ARCSIZE */
-  to    { transform: rotate(1080deg); } /* 4   * ARCSIZE */
-}
-
-/**
- * HACK: Even though the intention is to have the current .spinner-layer at
- * `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome
- * to do proper subpixel rendering for the elements being animated. This is
- * especially visible in Chrome 39 on Ubuntu 14.04. See:
- *
- * - https://github.com/Polymer/paper-spinner/issues/9
- * - https://code.google.com/p/chromium/issues/detail?id=436255
- */
-@-webkit-keyframes layer-1-fade-in-out {
-  from { opacity: 0.99; }
-  25% { opacity: 0.99; }
-  26% { opacity: 0; }
-  89% { opacity: 0; }
-  90% { opacity: 0.99; }
-  100% { opacity: 0.99; }
-}
-
-@keyframes layer-1-fade-in-out {
-  from { opacity: 0.99; }
-  25% { opacity: 0.99; }
-  26% { opacity: 0; }
-  89% { opacity: 0; }
-  90% { opacity: 0.99; }
-  100% { opacity: 0.99; }
-}
-
-@-webkit-keyframes layer-2-fade-in-out {
-  from { opacity: 0; }
-  15% { opacity: 0; }
-  25% { opacity: 0.99; }
-  50% { opacity: 0.99; }
-  51% { opacity: 0; }
-}
-
-@keyframes layer-2-fade-in-out {
-  from { opacity: 0; }
-  15% { opacity: 0; }
-  25% { opacity: 0.99; }
-  50% { opacity: 0.99; }
-  51% { opacity: 0; }
-}
-
-@-webkit-keyframes layer-3-fade-in-out {
-  from { opacity: 0; }
-  40% { opacity: 0; }
-  50% { opacity: 0.99; }
-  75% { opacity: 0.99; }
-  76% { opacity: 0; }
-}
-
-@keyframes layer-3-fade-in-out {
-  from { opacity: 0; }
-  40% { opacity: 0; }
-  50% { opacity: 0.99; }
-  75% { opacity: 0.99; }
-  76% { opacity: 0; }
-}
-
-@-webkit-keyframes layer-4-fade-in-out {
-  from { opacity: 0; }
-  65% { opacity: 0; }
-  75% { opacity: 0.99; }
-  90% { opacity: 0.99; }
-  100% { opacity: 0; }
-}
-
-@keyframes layer-4-fade-in-out {
-  from { opacity: 0; }
-  65% { opacity: 0; }
-  75% { opacity: 0.99; }
-  90% { opacity: 0.99; }
-  100% { opacity: 0; }
-}
-
-/**
- * Patch the gap that appear between the two adjacent div.circle-clipper while the
- * spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
- *
- * Update: the gap no longer appears on Chrome when .spinner-layer's opacity is 0.99,
- * but still does on Safari and IE.
- */
-.gap-patch {
-  position: absolute;
-  box-sizing: border-box;
-  top: 0;
-  left: 45%;
-  width: 10%;
-  height: 100%;
-  overflow: hidden;
-  border-color: inherit;
-}
-
-.gap-patch .circle {
-  width: 1000%;
-  left: -450%;
-}
-
-.circle-clipper {
-  display: inline-block;
-  position: relative;
-  width: 50%;
-  height: 100%;
-  overflow: hidden;
-  border-color: inherit;
-}
-
-.circle-clipper .circle {
-  width: 200%;
-}
-
-.circle {
-  box-sizing: border-box;
-  height: 100%;
-  border-width: 3px; /* STROKEWIDTH */
-  border-style: solid;
-  border-color: inherit;
-  border-bottom-color: transparent !important;
-  border-radius: 50%;
-  -webkit-animation: none;
-  animation: none;
-
-  @apply(--layout-fit);
-}
-
-.circle-clipper.left .circle {
-  border-right-color: transparent !important;
-  -webkit-transform: rotate(129deg);
-  transform: rotate(129deg);
-}
-
-.circle-clipper.right .circle {
-  left: -100%;
-  border-left-color: transparent !important;
-  -webkit-transform: rotate(-129deg);
-  transform: rotate(-129deg);
-}
-
-.active .circle-clipper.left .circle {
-  /* duration: ARCTIME */
-  -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-  animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-}
-
-.active .circle-clipper.right .circle {
-  /* duration: ARCTIME */
-  -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-  animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
-}
-
-@-webkit-keyframes left-spin {
-  from { -webkit-transform: rotate(130deg); }
-  50% { -webkit-transform: rotate(-5deg); }
-  to { -webkit-transform: rotate(130deg); }
-}
-
-@keyframes left-spin {
-  from { transform: rotate(130deg); }
-  50% { transform: rotate(-5deg); }
-  to { transform: rotate(130deg); }
-}
-
-@-webkit-keyframes right-spin {
-  from { -webkit-transform: rotate(-130deg); }
-  50% { -webkit-transform: rotate(5deg); }
-  to { -webkit-transform: rotate(-130deg); }
-}
-
-@keyframes right-spin {
-  from { transform: rotate(-130deg); }
-  50% { transform: rotate(5deg); }
-  to { transform: rotate(-130deg); }
-}
-
-#spinnerContainer.cooldown {
-  /* duration: SHRINK_TIME */
-  -webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
-  animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
-}
-
-@-webkit-keyframes fade-out {
-  from { opacity: 0.99; }
-  to { opacity: 0; }
-}
-
-@keyframes fade-out {
-  from { opacity: 0.99; }
-  to { opacity: 0; }
-}
diff --git a/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.html b/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.html
index 1a36945..dba346e 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.html
@@ -7,10 +7,13 @@
 Code distributed by Google as part of the polymer project is also
 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 --><html><head><link rel="import" href="../polymer/polymer.html">
-<link rel="import" href="../paper-styles/color.html">
 <link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../paper-styles/color.html">
+<link rel="import" href="paper-spinner-styles.html">
 
 <!--
+Material design: [Progress & activity](https://www.google.com/design/spec/components/progress-activity.html)
+
 Element providing material design circular spinner.
 
     <paper-spinner active></paper-spinner>
@@ -46,10 +49,8 @@
 -->
 
 </head><body><dom-module id="paper-spinner">
-
-  <link rel="import" type="css" href="paper-spinner.css">
-
   <template>
+    <style include="paper-spinner-styles"></style>
 
     <div id="spinnerContainer" class-name="[[_spinnerContainerClassName]]">
       <div class="spinner-layer layer-1">
@@ -92,7 +93,6 @@
         </div>
       </div>
     </div>
-
   </template>
 
   </dom-module>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-styles/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-styles/.bower.json
index 04e2128c..862c41b 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-styles/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-styles/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-styles",
-  "version": "1.0.11",
+  "version": "1.0.12",
   "description": "Common (global) styles for Material Design elements.",
   "authors": [
     "The Polymer Authors"
@@ -26,13 +26,14 @@
     "polymer": "Polymer/polymer#^1.0.0"
   },
   "devDependencies": {
-    "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+    "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+    "iron-component-page": "polymerelements/iron-component-page#^1.0.0"
   },
-  "_release": "1.0.11",
+  "_release": "1.0.12",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.11",
-    "commit": "347542e9ebe3e6e5f0830ee10e1c20c12956ff2c"
+    "tag": "v1.0.12",
+    "commit": "8ac5128a38249982982b3a1b3533d417d2dd7f18"
   },
   "_source": "git://github.com/PolymerElements/paper-styles.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-styles/bower.json b/third_party/polymer/v1_0/components-chromium/paper-styles/bower.json
index 7d28f69a..c4398ee 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-styles/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-styles/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-styles",
-  "version": "1.0.11",
+  "version": "1.0.12",
   "description": "Common (global) styles for Material Design elements.",
   "authors": [
     "The Polymer Authors"
@@ -26,6 +26,7 @@
     "polymer": "Polymer/polymer#^1.0.0"
   },
   "devDependencies": {
-    "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+    "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+    "iron-component-page": "polymerelements/iron-component-page#^1.0.0"
   }
 }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-styles/index.html b/third_party/polymer/v1_0/components-chromium/paper-styles/index.html
new file mode 100644
index 0000000..caf55c5
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-styles/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+  <title>paper-styles</title>
+  <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+  <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+  <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-styles/paper-styles.html b/third_party/polymer/v1_0/components-chromium/paper-styles/paper-styles.html
index 1e4fce5..7bee9dd 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-styles/paper-styles.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-styles/paper-styles.html
@@ -11,6 +11,30 @@
 <link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
 <link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
 
+<!--
+The `<paper-styles>` component provides simple ways to use Material Design CSS styles
+in your application. The following imports are available:
+
+1. [color.html](https://github.com/PolymerElements/paper-styles/blob/master/color.html):
+a complete list of the colors defined in the Material Design [palette](https://www.google.com/design/spec/style/color.html)
+
+2. [default-theme.html](https://github.com/PolymerElements/paper-styles/blob/master/default-theme.html): text,
+background and accent colors that match the default Material Design theme
+
+3. [shadow.html](https://github.com/PolymerElements/paper-styles/blob/master/shadow.html): Material Design
+[elevation](https://www.google.com/design/spec/what-is-material/elevation-shadows.html) and shadow styles
+
+4. [typography.html](https://github.com/PolymerElements/paper-styles/blob/master/typography.html):
+Material Design [font](http://www.google.com/design/spec/style/typography.html#typography-styles) styles and sizes
+
+5. [demo-pages.html](https://github.com/PolymerElements/paper-styles/blob/master/demo-pages.html): generic styles
+used in the PolymerElements demo pages
+
+@group Iron Elements
+@pseudoElement paper-styles
+@demo demo/index.html
+-->
+
 <link rel="import" href="color.html">
 <link rel="import" href="default-theme.html">
 <link rel="import" href="shadow.html">
diff --git a/third_party/polymer/v1_0/components-chromium/paper-styles/typography.html b/third_party/polymer/v1_0/components-chromium/paper-styles/typography.html
index ce78602..4a599f872 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-styles/typography.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-styles/typography.html
@@ -47,8 +47,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
       /* @apply(--paper-font-common-nowrap); */
       white-space: nowrap;
       overflow: hidden;
@@ -64,8 +63,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
       /* @apply(--paper-font-common-nowrap); */
       white-space: nowrap;
       overflow: hidden;
@@ -81,8 +79,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
 
       font-size: 45px;
       font-weight: 400;
@@ -94,8 +91,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
 
       font-size: 34px;
       font-weight: 400;
@@ -107,8 +103,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
 
       font-size: 24px;
       font-weight: 400;
@@ -120,8 +115,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
       /* @apply(--paper-font-common-nowrap); */
       white-space: nowrap;
       overflow: hidden;
@@ -136,8 +130,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
 
       font-size: 16px;
       font-weight: 400;
@@ -183,8 +176,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
       /* @apply(--paper-font-common-nowrap); */
       white-space: nowrap;
       overflow: hidden;
@@ -199,8 +191,7 @@
       /* @apply(--paper-font-common-base) */
       font-family: 'Roboto', 'Noto', sans-serif;
       -webkit-font-smoothing: antialiased;
-      /* @apply(--paper-font-common-expensive-kerning); */
-      text-rendering: optimizeLegibility;
+
       /* @apply(--paper-font-common-nowrap); */
       white-space: nowrap;
       overflow: hidden;
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/.bower.json b/third_party/polymer/v1_0/components-chromium/paper-tabs/.bower.json
index 129c621..d409a31 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-tabs/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-tabs",
-  "version": "1.0.4",
+  "version": "1.0.10",
   "license": "http://polymer.github.io/LICENSE.txt",
   "description": "Material design tabs",
   "private": true,
@@ -25,10 +25,10 @@
     "iron-iconset-svg": "polymerelements/iron-iconset-svg#^1.0.0",
     "iron-menu-behavior": "polymerelements/iron-menu-behavior#^1.0.0",
     "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
-    "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
     "paper-styles": "polymerelements/paper-styles#^1.0.0",
     "polymer": "Polymer/polymer#^1.0.0",
-    "paper-icon-button": "polymerelements/paper-icon-button#^1.0.0"
+    "paper-icon-button": "polymerelements/paper-icon-button#^1.0.0",
+    "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0"
   },
   "devDependencies": {
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
@@ -36,14 +36,15 @@
     "paper-toolbar": "polymerelements/paper-toolbar#^1.0.0",
     "test-fixture": "polymerelements/test-fixture#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
-    "web-component-tester": "*"
+    "web-component-tester": "*",
+    "iron-pages": "PolymerElements/iron-pages#^1.0.0"
   },
   "homepage": "https://github.com/PolymerElements/paper-tabs",
-  "_release": "1.0.4",
+  "_release": "1.0.10",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.4",
-    "commit": "b07b594cc08e7c97cda7e9b30b0bdd6c8969226c"
+    "tag": "v1.0.10",
+    "commit": "d9f518810b7313f3e5a29383d3bb86de0b260319"
   },
   "_source": "git://github.com/PolymerElements/paper-tabs.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/.travis.yml b/third_party/polymer/v1_0/components-chromium/paper-tabs/.travis.yml
new file mode 100644
index 0000000..27e770d
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+sudo: false
+matrix:
+  include:
+  - node_js: stable
+    script: xvfb-run wct
+    addons:
+      firefox: latest
+      apt:
+        sources:
+        - google-chrome
+        packages:
+        - google-chrome-stable
+  - node_js: node
+    script:
+    - |
+      if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
+        wct -s 'default'
+      fi
+before_script:
+- npm install web-component-tester
+- npm install bower
+- export PATH=$PWD/node_modules/.bin:$PATH
+- bower install
+env:
+  global:
+  - secure: ieKt2HWOdClqU7OyYA20DFlWduaM0IDk91lO7mWySQL6r55SSB4DnUCgVycQJf0L6S8vyY/fbC/vFP0notyz3MvMAz1NwpRzAI9mKkVWJuaBbm9Ql9PewjanX42chbz3XyqZofXVkfBywmj61NyPM7VRVwhEHmOeYgyFUyV9cls=
+  - secure: g7yrxdFIVMIjkYBKZ29FHUX3noS6u1lvjUmaAaG28rGaEfXK4XR9fhZABR+6ydAjLjdo+WUMvTp4oi6HYrb6ToByprEli/fTexjeGuagDc5r5R84u3CusBuw9YYHDjstHCBFmIZndD+r4PRXkWvYatciF9c0NCHoVrjTH/woe9g=
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/CONTRIBUTING.md b/third_party/polymer/v1_0/components-chromium/paper-tabs/CONTRIBUTING.md
new file mode 100644
index 0000000..7b101415
--- /dev/null
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+
+<!--
+This file is autogenerated based on
+https://github.com/PolymerElements/ContributionGuide/blob/master/CONTRIBUTING.md
+
+If you edit that file, it will get updated everywhere else.
+If you edit this file, your changes will get overridden :)
+-->
+# Polymer Elements
+## Guide for Contributors
+
+Polymer Elements are built in the open, and the Polymer authors eagerly encourage any and all forms of community contribution. When contributing, please follow these guidelines:
+
+### Filing Issues
+
+**If you are filing an issue to request a feature**, please provide a clear description of the feature. It can be helpful to describe answers to the following questions:
+
+ 1. **Who will use the feature?** _“As someone filling out a form…”_
+ 2. **When will they use the feature?** _“When I enter an invalid value…”_
+ 3. **What is the user’s goal?** _“I want to be visually notified that the value needs to be corrected…”_
+
+**If you are filing an issue to report a bug**, please provide:
+
+ 1. **A clear description of the bug and related expectations.** Consider using the following example template for reporting a bug:
+
+ ```markdown
+ The `paper-foo` element causes the page to turn pink when clicked.
+
+ ## Expected outcome
+
+ The page stays the same color.
+
+ ## Actual outcome
+
+ The page turns pink.
+
+ ## Steps to reproduce
+
+ 1. Put a `paper-foo` element in the page.
+ 2. Open the page in a web browser.
+ 3. Click the `paper-foo` element.
+ ```
+
+ 2. **A reduced test case that demonstrates the problem.** If possible, please include the test case as a JSBin. Start with this template to easily import and use relevant Polymer Elements: [http://jsbin.com/cagaye](http://jsbin.com/cagaye/edit?html,output).
+
+ 3. **A list of browsers where the problem occurs.** This can be skipped if the problem is the same across all browsers.
+
+### Submitting Pull Requests
+
+**Before creating a pull request**, please ensure that an issue exists for the corresponding change in the pull request that you intend to make. **If an issue does not exist, please create one per the guidelines above**. The goal is to discuss the design and necessity of the proposed change with Polymer authors and community before diving into a pull request.
+
+When submitting pull requests, please provide:
+
+ 1. **A reference to the corresponding issue** or issues that will be closed by the pull request. Please refer to these issues using the following syntax:
+
+ ```markdown
+ (For a single issue)
+ Fixes #20
+
+ (For multiple issues)
+ Fixes #32, #40
+ ```
+
+ 2. **A succinct description of the design** used to fix any related issues. For example:
+
+ ```markdown
+ This fixes #20 by removing styles that leaked which would cause the page to turn pink whenever `paper-foo` is clicked.
+ ```
+
+ 3. **At least one test for each bug fixed or feature added** as part of the pull request. Pull requests that fix bugs or add features without accompanying tests will not be considered.
+
+If a proposed change contains multiple commits, please [squash commits](https://www.google.com/url?q=http://blog.steveklabnik.com/posts/2012-11-08-how-to-squash-commits-in-a-github-pull-request) to as few as is necessary to succinctly express the change. A Polymer author can help you squash commits, so don’t be afraid to ask us if you need help with that!
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/README.md b/third_party/polymer/v1_0/components-chromium/paper-tabs/README.md
index d4744e2..4ab48a9 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-tabs/README.md
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/README.md
@@ -1,5 +1,23 @@
-paper-tabs
-============
+
+<!---
+
+This README is automatically generated from the comments in these files:
+paper-tab.html  paper-tabs.html
+
+Edit those files, and our readme bot will duplicate them over here!
+Edit this file, and the bot will squash your changes :)
+
+-->
+
+[![Build Status](https://travis-ci.org/PolymerElements/paper-tabs.svg?branch=master)](https://travis-ci.org/PolymerElements/paper-tabs)
+
+_[Demo and API Docs](https://elements.polymer-project.org/elements/paper-tabs)_
+
+
+##&lt;paper-tabs&gt;
+
+
+Material design: [Tabs](https://www.google.com/design/spec/components/tabs.html)
 
 `paper-tabs` makes it easy to explore and switch between different views or functional aspects of
 an app, or to browse categorized data sets.
@@ -8,13 +26,11 @@
 
 Example:
 
-```html
-<paper-tabs selected="0">
-  <paper-tab>TAB 1</paper-tab>
-  <paper-tab>TAB 2</paper-tab>
-  <paper-tab>TAB 3</paper-tab>
-</paper-tabs>
-```
+    <paper-tabs selected="0">
+      <paper-tab>TAB 1</paper-tab>
+      <paper-tab>TAB 2</paper-tab>
+      <paper-tab>TAB 3</paper-tab>
+    </paper-tabs>
 
 See <a href="#paper-tab">paper-tab</a> for more information about
 `paper-tab`.
@@ -22,35 +38,70 @@
 A common usage for `paper-tabs` is to use it along with `iron-pages` to switch
 between different views.
 
-```html
-<paper-tabs selected="{{selected}}">
-  <paper-tab>Tab 1</paper-tab>
-  <paper-tab>Tab 2</paper-tab>
-  <paper-tab>Tab 3</paper-tab>
-</paper-tabs>
+    <paper-tabs selected="{{selected}}">
+      <paper-tab>Tab 1</paper-tab>
+      <paper-tab>Tab 2</paper-tab>
+      <paper-tab>Tab 3</paper-tab>
+    </paper-tabs>
 
-<iron-pages selected="{{selected}}">
-  <div>Page 1</div>
-  <div>Page 2</div>
-  <div>Page 3</div>
-</iron-pages>
-```
+    <iron-pages selected="{{selected}}">
+      <div>Page 1</div>
+      <div>Page 2</div>
+      <div>Page 3</div>
+    </iron-pages>
+
 
 To use links in tabs, add `link` attribute to `paper-tab` and put an `<a>`
 element in `paper-tab`.
 
 Example:
 
-```html
-<paper-tabs selected="0">
-  <paper-tab link>
-    <a href="#link1" class="horizontal center-center layout">TAB ONE</a>
-  </paper-tab>
-  <paper-tab link>
-    <a href="#link2" class="horizontal center-center layout">TAB TWO</a>
-  </paper-tab>
-  <paper-tab link>
-    <a href="#link3" class="horizontal center-center layout">TAB THREE</a>
-  </paper-tab>
-</paper-tabs>
-```
+    <paper-tabs selected="0">
+      <paper-tab link>
+        <a href="#link1" class="horizontal center-center layout">TAB ONE</a>
+      </paper-tab>
+      <paper-tab link>
+        <a href="#link2" class="horizontal center-center layout">TAB TWO</a>
+      </paper-tab>
+      <paper-tab link>
+        <a href="#link3" class="horizontal center-center layout">TAB THREE</a>
+      </paper-tab>
+    </paper-tabs>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-tabs-selection-bar-color` | Color for the selection bar | `--paper-yellow-a100`
+`--paper-tabs` | Mixin applied to the tabs | `{}`
+
+
+
+##&lt;paper-tab&gt;
+
+
+`paper-tab` is styled to look like a tab.  It should be used in conjunction with
+`paper-tabs`.
+
+Example:
+
+    <paper-tabs selected="0">
+      <paper-tab>TAB 1</paper-tab>
+      <paper-tab>TAB 2</paper-tab>
+      <paper-tab>TAB 3</paper-tab>
+    </paper-tabs>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-tab-ink` | Ink color | `--paper-yellow-a100`
+`--paper-tab` | Mixin applied to the tab | `{}`
+`--paper-tab-content` | Mixin applied to the tab content | `{}`
+`--paper-tab-content-unselected` | Mixin applied to the tab content when the tab is not selected | `{}`
+
+
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/bower.json b/third_party/polymer/v1_0/components-chromium/paper-tabs/bower.json
index d533fa1..0bff065 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-tabs/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "paper-tabs",
-  "version": "1.0.4",
+  "version": "1.0.10",
   "license": "http://polymer.github.io/LICENSE.txt",
   "description": "Material design tabs",
   "private": true,
@@ -25,10 +25,10 @@
     "iron-iconset-svg": "polymerelements/iron-iconset-svg#^1.0.0",
     "iron-menu-behavior": "polymerelements/iron-menu-behavior#^1.0.0",
     "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
-    "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
     "paper-styles": "polymerelements/paper-styles#^1.0.0",
     "polymer": "Polymer/polymer#^1.0.0",
-    "paper-icon-button": "polymerelements/paper-icon-button#^1.0.0"
+    "paper-icon-button": "polymerelements/paper-icon-button#^1.0.0",
+    "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0"
   },
   "devDependencies": {
     "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
@@ -36,6 +36,7 @@
     "paper-toolbar": "polymerelements/paper-toolbar#^1.0.0",
     "test-fixture": "polymerelements/test-fixture#^1.0.0",
     "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
-    "web-component-tester": "*"
+    "web-component-tester": "*",
+    "iron-pages": "PolymerElements/iron-pages#^1.0.0"
   }
 }
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tab-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tab-extracted.js
index 149c193..db37bde 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tab-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tab-extracted.js
@@ -4,23 +4,10 @@
 
     behaviors: [
       Polymer.IronControlState,
-      Polymer.IronButtonState
+      Polymer.IronButtonState,
+      Polymer.PaperRippleBehavior
     ],
 
-    properties: {
-
-      /**
-       * If true, ink ripple effect is disabled.
-       *
-       * @attribute noink
-       */
-      noink: {
-        type: Boolean,
-        value: false
-      }
-
-    },
-
     hostAttributes: {
       role: 'tab'
     },
@@ -29,6 +16,12 @@
       down: '_updateNoink'
     },
 
+    ready: function() {
+      var ripple = this.getRipple();
+      ripple.initialOpacity = 0.95;
+      ripple.opacityDecayVelocity = 0.98;
+    },
+
     attached: function() {
       this._updateNoink();
     },
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tab.html b/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tab.html
index 4962579..0d65a86 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tab.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tab.html
@@ -11,7 +11,7 @@
 <link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
 <link rel="import" href="../iron-behaviors/iron-control-state.html">
 <link rel="import" href="../iron-behaviors/iron-button-state.html">
-<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-behaviors/paper-ripple-behavior.html">
 
 <!--
 `paper-tab` is styled to look like a tab.  It should be used in conjunction with
@@ -34,6 +34,7 @@
 `--paper-tab-ink` | Ink color | `--paper-yellow-a100`
 `--paper-tab` | Mixin applied to the tab | `{}`
 `--paper-tab-content` | Mixin applied to the tab content | `{}`
+`--paper-tab-content-unselected` | Mixin applied to the tab content when the tab is not selected | `{}`
 
 -->
 
@@ -74,6 +75,8 @@
 
     :host(:not(.iron-selected)) > .tab-content {
       opacity: 0.8;
+
+      @apply(--paper-tab-content-unselected);
     }
 
     :host(:focus) .tab-content {
@@ -81,9 +84,8 @@
       font-weight: 700;
     }
 
-    #ink {
+    paper-ripple {
       color: var(--paper-tab-ink, --paper-yellow-a100);
-      pointer-events: none;
     }
 
     .tab-content > ::content > a {
@@ -104,10 +106,6 @@
       <content></content>
     </div>
 
-    <template is="dom-if" if="[[!noink]]">
-      <paper-ripple id="ink" initial-opacity="0.95" opacity-decay-velocity="0.98"></paper-ripple>
-    </template>
-
   </template>
 
 </dom-module>
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs-extracted.js
index 4b1765df6..5ef4d19 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs-extracted.js
@@ -10,11 +10,14 @@
     properties: {
 
       /**
-       * If true, ink ripple effect is disabled.
+       * If true, ink ripple effect is disabled. When this property is changed,
+       * all descendant `<paper-tab>` elements have their `noink` property
+       * changed to the new value as well.
        */
       noink: {
         type: Boolean,
-        value: false
+        value: false,
+        observer: '_noinkChanged'
       },
 
       /**
@@ -113,10 +116,27 @@
       'iron-deselect': '_onIronDeselect'
     },
 
+    created: function() {
+      this._holdJob = null;
+    },
+
     ready: function() {
       this.setScrollDirection('y', this.$.tabsContainer);
     },
 
+    _noinkChanged: function(noink) {
+      var childTabs = Polymer.dom(this).querySelectorAll('paper-tab');
+      childTabs.forEach(noink ? this._setNoinkAttribute : this._removeNoinkAttribute);
+    },
+
+    _setNoinkAttribute: function(element) {
+      element.setAttribute('noink', '');
+    },
+
+    _removeNoinkAttribute: function(element) {
+      element.removeAttribute('noink');
+    },
+
     _computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButtons) {
       if (!scrollable || hideScrollButtons) {
         return 'hidden';
diff --git a/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs.html b/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs.html
index 59483f3..9e8dcfc 100644
--- a/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs.html
+++ b/third_party/polymer/v1_0/components-chromium/paper-tabs/paper-tabs.html
@@ -103,6 +103,10 @@
       @apply(--paper-tabs);
     }
 
+    :host-context([dir=rtl]) {
+      @apply(--layout-horizontal-reverse);
+    }
+
     #tabsContainer {
       position: relative;
       height: 100%;
@@ -129,8 +133,10 @@
     }
 
     paper-icon-button {
-      width: 24px;
-      padding: 16px;
+      width: 48px;
+      height: 48px;
+      padding: 12px;
+      margin: 0 4px;
     }
 
     #selectionBar {
diff --git a/third_party/polymer/v1_0/components-chromium/polymer-externs/.bower.json b/third_party/polymer/v1_0/components-chromium/polymer-externs/.bower.json
index cc44024..52bf33b 100644
--- a/third_party/polymer/v1_0/components-chromium/polymer-externs/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/polymer-externs/.bower.json
@@ -1,12 +1,12 @@
 {
   "name": "polymer-externs",
   "homepage": "https://github.com/PolymerLabs/polymer-externs",
-  "version": "1.0.12",
-  "_release": "1.0.12",
+  "version": "1.0.14",
+  "_release": "1.0.14",
   "_resolution": {
     "type": "version",
-    "tag": "v1.0.12",
-    "commit": "2f7588794d386b269c437dd681990fba2640ebab"
+    "tag": "v1.0.14",
+    "commit": "d4465d6295fc747d95641a91912b802f49180d43"
   },
   "_source": "git://github.com/PolymerLabs/polymer-externs.git",
   "_target": "^1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/polymer-externs/polymer.externs.js b/third_party/polymer/v1_0/components-chromium/polymer-externs/polymer.externs.js
index 5a622805..41a7972 100644
--- a/third_party/polymer/v1_0/components-chromium/polymer-externs/polymer.externs.js
+++ b/third_party/polymer/v1_0/components-chromium/polymer-externs/polymer.externs.js
@@ -438,6 +438,13 @@
 PolymerElement.prototype.importHref = function(href, onload, onerror) {};
 
 /**
+ * Checks whether an element is in this element's light DOM tree.
+ * @param {HTMLElement=} node The element to be checked.
+ * @return {boolean} true if node is in this element's light DOM tree.
+ */
+PolymerElement.prototype.isLightDescendant = function(node) {};
+
+/**
  * Delete an element from an array.
  * @param {!Array|string} array Path to array from which to remove the item (or
  *     the array itself).
@@ -473,9 +480,6 @@
  */
 PolymerElement.prototype.customStyle;
 
-/** @type {Node|undefined} */
-PolymerElement.prototype.shadyRoot;
-
 /**
  * Logs a message to the console.
  *
@@ -598,6 +602,15 @@
 /** @param {string} attribute */
 PolymerDomApi.prototype.removeAttribute = function(attribute) {};
 
+/**
+ * @param {!Function} callback
+ * @return {!{fn: (!Function|undefined), _nodes: !Array<!Node>}}
+ */
+PolymerDomApi.prototype.observeNodes = function(callback) {};
+
+/** @param {!{fn: (!Function|undefined), _nodes: !Array<!Node>}} handle */
+PolymerDomApi.prototype.unobserveNodes = function(handle) {};
+
 /** @type {?DOMTokenList} */
 PolymerDomApi.prototype.classList;
 
diff --git a/third_party/polymer/v1_0/components-chromium/polymer/.bower.json b/third_party/polymer/v1_0/components-chromium/polymer/.bower.json
index 7e35d0c..abf79d8 100644
--- a/third_party/polymer/v1_0/components-chromium/polymer/.bower.json
+++ b/third_party/polymer/v1_0/components-chromium/polymer/.bower.json
@@ -1,6 +1,6 @@
 {
   "name": "polymer",
-  "version": "1.1.5",
+  "version": "1.2.1",
   "main": [
     "polymer.html"
   ],
@@ -25,11 +25,11 @@
   },
   "private": true,
   "homepage": "https://github.com/Polymer/polymer",
-  "_release": "1.1.5",
+  "_release": "1.2.1",
   "_resolution": {
     "type": "version",
-    "tag": "v1.1.5",
-    "commit": "4c94736fac6681e84ec8c00da53484c5d3c2226b"
+    "tag": "v1.2.1",
+    "commit": "be2d57a329244735ca7aac34ac56c96b6270ae79"
   },
   "_source": "git://github.com/Polymer/polymer.git",
   "_target": "^v1.0.0",
diff --git a/third_party/polymer/v1_0/components-chromium/polymer/bower.json b/third_party/polymer/v1_0/components-chromium/polymer/bower.json
index a7d4b0a..bc97dc4 100644
--- a/third_party/polymer/v1_0/components-chromium/polymer/bower.json
+++ b/third_party/polymer/v1_0/components-chromium/polymer/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "polymer",
-  "version": "1.1.5",
+  "version": "1.2.1",
   "main": [
     "polymer.html"
   ],
diff --git a/third_party/polymer/v1_0/components-chromium/polymer/build.log b/third_party/polymer/v1_0/components-chromium/polymer/build.log
index 8a8463ad..a625291 100644
--- a/third_party/polymer/v1_0/components-chromium/polymer/build.log
+++ b/third_party/polymer/v1_0/components-chromium/polymer/build.log
@@ -1,26 +1,27 @@
 BUILD LOG
 ---------
-Build Time: 2015-10-08T14:06:39-0700
+Build Time: 2015-10-29T15:32:35-0700
 
 NODEJS INFORMATION
 ==================
-nodejs: v4.1.2
-del: 1.2.0
-gulp-rename: 1.2.2
+nodejs: v4.2.1
 gulp: 3.9.0
 gulp-audit: 1.0.0
-gulp-replace: 0.5.3
+gulp-rename: 1.2.2
 gulp-vulcanize: 6.0.1
-polyclean: 1.2.0
 lazypipe: 0.2.4
-run-sequence: 1.1.1
+polyclean: 1.2.0
+web-component-tester: 3.3.29
+run-sequence: 1.1.4
+del: 1.2.1
+gulp-replace: 0.5.4
 
 REPO REVISIONS
 ==============
-polymer: 574855a644bcc25ee26c30e0dd881a395fad67b6
+polymer: 5a755342ef6c1bd404d3b4861c3b82d10d57b2ec
 
 BUILD HASHES
 ============
-polymer-mini.html: 72c032eacc45c63431054c111d0ce86357eb07f3
-polymer-micro.html: 62d773e546d387df86bc1b33a3cb61c3c1c9bc76
-polymer.html: 5c626b1aba3107c12cee378876d13b8780fdec67
\ No newline at end of file
+polymer-mini.html: 88f650dd1b5691577f998049967a6dc9dc456e48
+polymer-micro.html: 2261be50c3d6dfe7bd1ae9051a1115f409ef64c3
+polymer.html: 0da5e9c32e9ce759647ba6bc64618bb772890acd
\ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/polymer/polymer-extracted.js b/third_party/polymer/v1_0/components-chromium/polymer/polymer-extracted.js
index e11ba9f1..4f774b5 100644
--- a/third_party/polymer/v1_0/components-chromium/polymer/polymer-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/polymer/polymer-extracted.js
@@ -9,22 +9,66 @@
 _parseNodeAnnotations: function (node, list) {
 return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, list) : this._parseElementAnnotations(node, list);
 },
-_testEscape: function (value) {
-var escape = value.slice(0, 2);
-if (escape === '{{' || escape === '[[') {
-return escape;
+_bindingRegex: /([^{[]*)({{|\[\[)([^}\]]*)(?:]]|}})/g,
+_parseBindings: function (text) {
+var re = this._bindingRegex;
+var parts = [];
+var m, lastIndex;
+while ((m = re.exec(text)) !== null) {
+if (m[1]) {
+parts.push({ literal: m[1] });
+}
+var mode = m[2][0];
+var value = m[3].trim();
+var negate = false;
+if (value[0] == '!') {
+negate = true;
+value = value.substring(1).trim();
+}
+var customEvent, notifyEvent, colon;
+if (mode == '{' && (colon = value.indexOf('::')) > 0) {
+notifyEvent = value.substring(colon + 2);
+value = value.substring(0, colon);
+customEvent = true;
+}
+parts.push({
+compoundIndex: parts.length,
+value: value,
+mode: mode,
+negate: negate,
+event: notifyEvent,
+customEvent: customEvent
+});
+lastIndex = re.lastIndex;
+}
+if (lastIndex && lastIndex < text.length) {
+var literal = text.substring(lastIndex);
+if (literal) {
+parts.push({ literal: literal });
+}
+}
+if (parts.length) {
+return parts;
 }
 },
+_literalFromParts: function (parts) {
+var s = '';
+for (var i = 0; i < parts.length; i++) {
+var literal = parts[i].literal;
+s += literal || '';
+}
+return s;
+},
 _parseTextNodeAnnotation: function (node, list) {
-var v = node.textContent;
-var escape = this._testEscape(v);
-if (escape) {
-node.textContent = ' ';
+var parts = this._parseBindings(node.textContent);
+if (parts) {
+node.textContent = this._literalFromParts(parts) || ' ';
 var annote = {
 bindings: [{
 kind: 'text',
-mode: escape[0],
-value: v.slice(2, -2).trim()
+name: 'textContent',
+parts: parts,
+isCompound: parts.length !== 1
 }]
 };
 list.push(annote);
@@ -86,62 +130,50 @@
 });
 },
 _parseNodeAttributeAnnotations: function (node, annotation) {
-for (var i = node.attributes.length - 1, a; a = node.attributes[i]; i--) {
-var n = a.name, v = a.value;
-if (n === 'id' && !this._testEscape(v)) {
-annotation.id = v;
-} else if (n.slice(0, 3) === 'on-') {
+var attrs = Array.prototype.slice.call(node.attributes);
+for (var i = attrs.length - 1, a; a = attrs[i]; i--) {
+var n = a.name;
+var v = a.value;
+var b;
+if (n.slice(0, 3) === 'on-') {
 node.removeAttribute(n);
 annotation.events.push({
 name: n.slice(3),
 value: v
 });
-} else {
-var b = this._parseNodeAttributeAnnotation(node, n, v);
-if (b) {
+} else if (b = this._parseNodeAttributeAnnotation(node, n, v)) {
 annotation.bindings.push(b);
-}
+} else if (n === 'id') {
+annotation.id = v;
 }
 }
 },
-_parseNodeAttributeAnnotation: function (node, n, v) {
-var escape = this._testEscape(v);
-if (escape) {
-var customEvent;
-var name = n;
-var mode = escape[0];
-v = v.slice(2, -2).trim();
-var not = false;
-if (v[0] == '!') {
-v = v.substring(1);
-not = true;
-}
+_parseNodeAttributeAnnotation: function (node, name, value) {
+var parts = this._parseBindings(value);
+if (parts) {
+var origName = name;
 var kind = 'property';
-if (n[n.length - 1] == '$') {
-name = n.slice(0, -1);
+if (name[name.length - 1] == '$') {
+name = name.slice(0, -1);
 kind = 'attribute';
 }
-var notifyEvent, colon;
-if (mode == '{' && (colon = v.indexOf('::')) > 0) {
-notifyEvent = v.substring(colon + 2);
-v = v.substring(0, colon);
-customEvent = true;
+var literal = this._literalFromParts(parts);
+if (literal && kind == 'attribute') {
+node.setAttribute(name, literal);
 }
-if (node.localName == 'input' && n == 'value') {
-node.setAttribute(n, '');
+if (node.localName == 'input' && name == 'value') {
+node.setAttribute(origName, '');
 }
-node.removeAttribute(n);
+node.removeAttribute(origName);
 if (kind === 'property') {
 name = Polymer.CaseMap.dashToCamelCase(name);
 }
 return {
 kind: kind,
-mode: mode,
 name: name,
-value: v,
-negate: not,
-event: notifyEvent,
-customEvent: customEvent
+parts: parts,
+literal: literal,
+isCompound: parts.length !== 1
 };
 }
 },
@@ -232,9 +264,14 @@
 var note = notes[i];
 for (var j = 0; j < note.bindings.length; j++) {
 var b = note.bindings[j];
-b.signature = this._parseMethod(b.value);
-if (!b.signature) {
-b.model = this._modelForPath(b.value);
+for (var k = 0; k < b.parts.length; k++) {
+var p = b.parts[k];
+if (!p.literal) {
+p.signature = this._parseMethod(p.value);
+if (!p.signature) {
+p.model = this._modelForPath(p.value);
+}
+}
 }
 }
 if (note.templateContent) {
@@ -245,10 +282,12 @@
 bindings.push({
 index: note.index,
 kind: 'property',
-mode: '{',
 name: '_parent_' + prop,
+parts: [{
+mode: '{',
 model: prop,
 value: prop
+}]
 });
 }
 note.bindings = note.bindings.concat(bindings);
@@ -259,15 +298,17 @@
 var pp = {};
 notes.forEach(function (n) {
 n.bindings.forEach(function (b) {
-if (b.signature) {
-var args = b.signature.args;
+b.parts.forEach(function (p) {
+if (p.signature) {
+var args = p.signature.args;
 for (var k = 0; k < args.length; k++) {
 pp[args[k].model] = true;
 }
 } else {
-pp[b.model] = true;
+pp[p.model] = true;
 }
 });
+});
 if (n.templateContent) {
 var tpp = n.templateContent._parentProps;
 Polymer.Base.mixin(pp, tpp);
@@ -286,15 +327,43 @@
 this._marshalAnnotatedListeners();
 }
 },
-_configureAnnotationReferences: function () {
-this._configureTemplateContent();
-},
-_configureTemplateContent: function () {
-this._notes.forEach(function (note, i) {
-if (note.templateContent) {
-this._nodes[i]._content = note.templateContent;
+_configureAnnotationReferences: function (config) {
+var notes = this._notes;
+var nodes = this._nodes;
+for (var i = 0; i < notes.length; i++) {
+var note = notes[i];
+var node = nodes[i];
+this._configureTemplateContent(note, node);
+this._configureCompoundBindings(note, node);
 }
-}, this);
+},
+_configureTemplateContent: function (note, node) {
+if (note.templateContent) {
+node._content = note.templateContent;
+}
+},
+_configureCompoundBindings: function (note, node) {
+var bindings = note.bindings;
+for (var i = 0; i < bindings.length; i++) {
+var binding = bindings[i];
+if (binding.isCompound) {
+var storage = node.__compoundStorage__ || (node.__compoundStorage__ = {});
+var parts = binding.parts;
+var literals = new Array(parts.length);
+for (var j = 0; j < parts.length; j++) {
+literals[j] = parts[j].literal;
+}
+var name = binding.name;
+storage[name] = literals;
+if (binding.literal && binding.kind == 'property') {
+if (node._configValue) {
+node._configValue(name, binding.literal);
+} else {
+node[name] = binding.literal;
+}
+}
+}
+}
 },
 _marshalIdNodes: function () {
 this.$ = {};
@@ -1086,7 +1155,9 @@
 this._lastVal += len;
 }
 };
-new (window.MutationObserver || JsMutationObserver)(Polymer.Async._atEndOfMicrotask.bind(Polymer.Async)).observe(Polymer.Async._twiddle, { characterData: true });
+new window.MutationObserver(function () {
+Polymer.Async._atEndOfMicrotask();
+}).observe(Polymer.Async._twiddle, { characterData: true });
 Polymer.Debounce = function () {
 var Async = Polymer.Async;
 var Debouncer = function (context) {
@@ -1168,6 +1239,32 @@
 Polymer.dom(toElement).setAttribute(name, '');
 }
 },
+getEffectiveChildNodes: function () {
+return Polymer.dom(this).getEffectiveChildNodes();
+},
+getEffectiveChildren: function () {
+var list = Polymer.dom(this).getEffectiveChildNodes();
+return list.filter(function (n) {
+return n.nodeType === Node.ELEMENT_NODE;
+});
+},
+getEffectiveTextContent: function () {
+var cn = this.getEffectiveChildNodes();
+var tc = [];
+for (var i = 0, c; c = cn[i]; i++) {
+if (c.nodeType !== Node.COMMENT_NODE) {
+tc.push(Polymer.dom(c).textContent);
+}
+}
+return tc.join('');
+},
+queryEffectiveChildren: function (slctr) {
+var e$ = Polymer.dom(this).queryDistributedElements(slctr);
+return e$ && e$[0];
+},
+queryAllEffectiveChildren: function (slctr) {
+return Polymer.dom(this).queryAllDistributedElements(slctr);
+},
 getContentChildNodes: function (slctr) {
 var content = Polymer.dom(this.root).querySelector(slctr || 'content');
 return content ? Polymer.dom(content).getDistributedNodes() : [];
@@ -1205,7 +1302,7 @@
 return path.splice(index, 1);
 }
 } else {
-var arr = this.get(path);
+var arr = this._get(path);
 index = arr.indexOf(item);
 if (index >= 0) {
 return this.splice(path, index, 1);
@@ -1244,7 +1341,7 @@
 return elt;
 },
 isLightDescendant: function (node) {
-return this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot();
+return this !== node && this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot();
 },
 isLocalDescendant: function (node) {
 return this.root === Polymer.dom(node).getOwnerRoot();
@@ -1387,7 +1484,7 @@
 return function (e, target) {
 if (!bogusTest(e, target)) {
 if (e.detail && e.detail.path) {
-this.notifyPath(this._fixPath(path, property, e.detail.path), e.detail.value);
+this._notifyPath(this._fixPath(path, property, e.detail.path), e.detail.value);
 } else {
 var value = target[property];
 if (!isStructured) {
@@ -1413,16 +1510,16 @@
 };
 Polymer.Base.extend(Polymer.Bind, {
 _shouldAddListener: function (effect) {
-return effect.name && effect.mode === '{' && !effect.negate && effect.kind != 'attribute';
+return effect.name && effect.kind != 'attribute' && effect.kind != 'text' && !effect.isCompound && effect.parts[0].mode === '{' && !effect.parts[0].negate;
 },
 _annotationEffect: function (source, value, effect) {
 if (source != effect.value) {
-value = this.get(effect.value);
+value = this._get(effect.value);
 this.__data__[effect.value] = value;
 }
 var calc = effect.negate ? !value : value;
 if (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) {
-return this._applyEffectValue(calc, effect);
+return this._applyEffectValue(effect, calc);
 }
 },
 _reflectEffect: function (source) {
@@ -1460,7 +1557,7 @@
 if (args) {
 var fn = this[effect.method];
 if (fn) {
-this.__setProperty(effect.property, fn.apply(this, args));
+this.__setProperty(effect.name, fn.apply(this, args));
 } else {
 this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined'));
 }
@@ -1476,7 +1573,7 @@
 if (effect.negate) {
 computedvalue = !computedvalue;
 }
-this._applyEffectValue(computedvalue, effect);
+this._applyEffectValue(effect, computedvalue);
 }
 } else {
 computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined'));
@@ -1492,7 +1589,7 @@
 if (arg.literal) {
 v = arg.value;
 } else if (arg.structured) {
-v = Polymer.Base.get(name, model);
+v = Polymer.Base._get(name, model);
 } else {
 v = model[name];
 }
@@ -1555,7 +1652,7 @@
 method: sig.method,
 args: sig.args,
 trigger: arg,
-property: name
+name: name
 });
 }, this);
 },
@@ -1593,35 +1690,49 @@
 },
 _addAnnotationEffect: function (note, index) {
 if (Polymer.Bind._shouldAddListener(note)) {
-Polymer.Bind._addAnnotatedListener(this, index, note.name, note.value, note.event);
+Polymer.Bind._addAnnotatedListener(this, index, note.name, note.parts[0].value, note.parts[0].event);
 }
-if (note.signature) {
-this._addAnnotatedComputationEffect(note, index);
-} else {
-note.index = index;
-this._addPropertyEffect(note.model, 'annotation', note);
+for (var i = 0; i < note.parts.length; i++) {
+var part = note.parts[i];
+if (part.signature) {
+this._addAnnotatedComputationEffect(note, part, index);
+} else if (!part.literal) {
+this._addPropertyEffect(part.model, 'annotation', {
+kind: note.kind,
+index: index,
+name: note.name,
+value: part.value,
+isCompound: note.isCompound,
+compoundIndex: part.compoundIndex,
+event: part.event,
+customEvent: part.customEvent,
+negate: part.negate
+});
+}
 }
 },
-_addAnnotatedComputationEffect: function (note, index) {
-var sig = note.signature;
+_addAnnotatedComputationEffect: function (note, part, index) {
+var sig = part.signature;
 if (sig.static) {
-this.__addAnnotatedComputationEffect('__static__', index, note, sig, null);
+this.__addAnnotatedComputationEffect('__static__', index, note, part, null);
 } else {
 sig.args.forEach(function (arg) {
 if (!arg.literal) {
-this.__addAnnotatedComputationEffect(arg.model, index, note, sig, arg);
+this.__addAnnotatedComputationEffect(arg.model, index, note, part, arg);
 }
 }, this);
 }
 },
-__addAnnotatedComputationEffect: function (property, index, note, sig, trigger) {
+__addAnnotatedComputationEffect: function (property, index, note, part, trigger) {
 this._addPropertyEffect(property, 'annotatedComputation', {
 index: index,
+isCompound: note.isCompound,
+compoundIndex: part.compoundIndex,
 kind: note.kind,
-property: note.name,
-negate: note.negate,
-method: sig.method,
-args: sig.args,
+name: note.name,
+negate: part.negate,
+method: part.signature.method,
+args: part.signature.args,
 trigger: trigger
 });
 },
@@ -1690,9 +1801,14 @@
 Polymer.Bind.prepareInstance(this);
 Polymer.Bind.setupBindListeners(this);
 },
-_applyEffectValue: function (value, info) {
+_applyEffectValue: function (info, value) {
 var node = this._nodes[info.index];
-var property = info.property || info.name || 'textContent';
+var property = info.name;
+if (info.isCompound) {
+var storage = node.__compoundStorage__[property];
+storage[info.compoundIndex] = value;
+value = storage.join('');
+}
 if (info.kind == 'attribute') {
 this.serializeValueToAttribute(value, property, node);
 } else {
@@ -1772,10 +1888,10 @@
 var fx = fx$[p];
 if (fx) {
 for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) {
-if (x.kind === 'annotation') {
+if (x.kind === 'annotation' && !x.isCompound) {
 var node = this._nodes[x.effect.index];
 if (node._configValue) {
-var value = p === x.effect.value ? config[p] : this.get(x.effect.value, config);
+var value = p === x.effect.value ? config[p] : this._get(x.effect.value, config);
 node._configValue(x.effect.name, value);
 }
 }
@@ -1822,11 +1938,16 @@
 'use strict';
 Polymer.Base._addFeature({
 notifyPath: function (path, value, fromAbove) {
+var info = {};
+this._get(path, this, info);
+this._notifyPath(info.path, value, fromAbove);
+},
+_notifyPath: function (path, value, fromAbove) {
 var old = this._propertySetter(path, value);
 if (old !== value && (old === old || value === value)) {
 this._pathEffector(path, value);
 if (!fromAbove) {
-this._notifyPath(path, value);
+this._notifyPathUp(path, value);
 }
 return true;
 }
@@ -1853,41 +1974,67 @@
 if (parts.length > 1) {
 for (var i = 0; i < parts.length - 1; i++) {
 var part = parts[i];
+if (array && part[0] == '#') {
+prop = Polymer.Collection.get(array).getItem(part);
+} else {
 prop = prop[part];
-if (array && parseInt(part) == part) {
+if (array && parseInt(part, 10) == part) {
 parts[i] = Polymer.Collection.get(array).getKey(prop);
 }
+}
 if (!prop) {
 return;
 }
 array = Array.isArray(prop) ? prop : null;
 }
-if (array && parseInt(last) == last) {
+if (array) {
 var coll = Polymer.Collection.get(array);
+if (last[0] == '#') {
+var key = last;
+var old = coll.getItem(key);
+last = array.indexOf(old);
+coll.setItem(key, value);
+} else if (parseInt(last, 10) == last) {
 var old = prop[last];
 var key = coll.getKey(old);
 parts[i] = key;
 coll.setItem(key, value);
 }
+}
 prop[last] = value;
 if (!root) {
-this.notifyPath(parts.join('.'), value);
+this._notifyPath(parts.join('.'), value);
 }
 } else {
 prop[path] = value;
 }
 },
 get: function (path, root) {
+return this._get(path, root);
+},
+_get: function (path, root, info) {
 var prop = root || this;
 var parts = this._getPathParts(path);
-var last = parts.pop();
-while (parts.length) {
-prop = prop[parts.shift()];
+var array;
+for (var i = 0; i < parts.length; i++) {
 if (!prop) {
 return;
 }
+var part = parts[i];
+if (array && part[0] == '#') {
+prop = Polymer.Collection.get(array).getItem(part);
+} else {
+prop = prop[part];
+if (info && array && parseInt(part, 10) == part) {
+parts[i] = Polymer.Collection.get(array).getKey(prop);
 }
-return prop[last];
+}
+array = Array.isArray(prop) ? prop : null;
+}
+if (info) {
+info.path = parts.join('.');
+}
+return prop;
 },
 _pathEffector: function (path, value) {
 var model = this._modelForPath(path);
@@ -1909,9 +2056,9 @@
 Polymer.Bind._annotationEffect.call(this, path, value, effect);
 } else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) {
 var node = this._nodes[effect.index];
-if (node && node.notifyPath) {
+if (node && node._notifyPath) {
 var p = this._fixPath(effect.name, effect.value, path);
-node.notifyPath(p, value, true);
+node._notifyPath(p, value, true);
 }
 }
 },
@@ -1951,16 +2098,16 @@
 for (var a in this._boundPaths) {
 var b = this._boundPaths[a];
 if (path.indexOf(a + '.') == 0) {
-this.notifyPath(this._fixPath(b, a, path), value);
+this._notifyPath(this._fixPath(b, a, path), value);
 } else if (path.indexOf(b + '.') == 0) {
-this.notifyPath(this._fixPath(a, b, path), value);
+this._notifyPath(this._fixPath(a, b, path), value);
 }
 }
 },
 _fixPath: function (property, root, path) {
 return property + path.slice(root.length);
 },
-_notifyPath: function (path, value) {
+_notifyPathUp: function (path, value) {
 var rootName = this._modelForPath(path);
 var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);
 var eventName = dashCaseName + this._EVENT_CHANGED;
@@ -1974,47 +2121,62 @@
 return dot < 0 ? path : path.slice(0, dot);
 },
 _EVENT_CHANGED: '-changed',
+notifySplices: function (path, splices) {
+var info = {};
+var array = this._get(path, this, info);
+this._notifySplices(array, info.path, splices);
+},
+_notifySplices: function (array, path, splices) {
+var change = {
+keySplices: Polymer.Collection.applySplices(array, splices),
+indexSplices: splices
+};
+if (!array.hasOwnProperty('splices')) {
+Object.defineProperty(array, 'splices', {
+configurable: true,
+writable: true
+});
+}
+array.splices = change;
+this._notifyPath(path + '.splices', change);
+this._notifyPath(path + '.length', array.length);
+change.keySplices = null;
+change.indexSplices = null;
+},
 _notifySplice: function (array, path, index, added, removed) {
-var splices = [{
+this._notifySplices(array, path, [{
 index: index,
 addedCount: added,
 removed: removed,
 object: array,
 type: 'splice'
-}];
-var change = {
-keySplices: Polymer.Collection.applySplices(array, splices),
-indexSplices: splices
-};
-this.set(path + '.splices', change);
-if (added != removed.length) {
-this.notifyPath(path + '.length', array.length);
-}
-change.keySplices = null;
-change.indexSplices = null;
+}]);
 },
 push: function (path) {
-var array = this.get(path);
+var info = {};
+var array = this._get(path, this, info);
 var args = Array.prototype.slice.call(arguments, 1);
 var len = array.length;
 var ret = array.push.apply(array, args);
 if (args.length) {
-this._notifySplice(array, path, len, args.length, []);
+this._notifySplice(array, info.path, len, args.length, []);
 }
 return ret;
 },
 pop: function (path) {
-var array = this.get(path);
+var info = {};
+var array = this._get(path, this, info);
 var hadLength = Boolean(array.length);
 var args = Array.prototype.slice.call(arguments, 1);
 var ret = array.pop.apply(array, args);
 if (hadLength) {
-this._notifySplice(array, path, array.length, 0, [ret]);
+this._notifySplice(array, info.path, array.length, 0, [ret]);
 }
 return ret;
 },
 splice: function (path, start, deleteCount) {
-var array = this.get(path);
+var info = {};
+var array = this._get(path, this, info);
 if (start < 0) {
 start = array.length - Math.floor(-start);
 } else {
@@ -2027,26 +2189,28 @@
 var ret = array.splice.apply(array, args);
 var addedCount = Math.max(args.length - 2, 0);
 if (addedCount || ret.length) {
-this._notifySplice(array, path, start, addedCount, ret);
+this._notifySplice(array, info.path, start, addedCount, ret);
 }
 return ret;
 },
 shift: function (path) {
-var array = this.get(path);
+var info = {};
+var array = this._get(path, this, info);
 var hadLength = Boolean(array.length);
 var args = Array.prototype.slice.call(arguments, 1);
 var ret = array.shift.apply(array, args);
 if (hadLength) {
-this._notifySplice(array, path, 0, 0, [ret]);
+this._notifySplice(array, info.path, 0, 0, [ret]);
 }
 return ret;
 },
 unshift: function (path) {
-var array = this.get(path);
+var info = {};
+var array = this._get(path, this, info);
 var args = Array.prototype.slice.call(arguments, 1);
 var ret = array.unshift.apply(array, args);
 if (args.length) {
-this._notifySplice(array, path, 0, args.length, []);
+this._notifySplice(array, info.path, 0, args.length, []);
 }
 return ret;
 },
@@ -2054,8 +2218,10 @@
 this.mixin(model, {
 fire: Polymer.Base.fire,
 notifyPath: Polymer.Base.notifyPath,
+_get: Polymer.Base._get,
 _EVENT_CHANGED: Polymer.Base._EVENT_CHANGED,
 _notifyPath: Polymer.Base._notifyPath,
+_notifyPathUp: Polymer.Base._notifyPathUp,
 _pathEffector: Polymer.Base._pathEffector,
 _annotationPathEffect: Polymer.Base._annotationPathEffect,
 _complexObserverPathEffect: Polymer.Base._complexObserverPathEffect,
@@ -2063,7 +2229,8 @@
 _computePathEffect: Polymer.Base._computePathEffect,
 _modelForPath: Polymer.Base._modelForPath,
 _pathMatchesEffect: Polymer.Base._pathMatchesEffect,
-_notifyBoundPaths: Polymer.Base._notifyBoundPaths
+_notifyBoundPaths: Polymer.Base._notifyBoundPaths,
+_getPathParts: Polymer.Base._getPathParts
 });
 }
 });
@@ -2200,7 +2367,7 @@
 comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim,
 port: /@import[^;]*;/gim,
 customProp: /(?:^|[\s;])--[^;{]*?:[^{};]*?(?:[;\n]|$)/gim,
-mixinProp: /(?:^|[\s;])--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\n]|$)?/gim,
+mixinProp: /(?:^|[\s;])?--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\n]|$)?/gim,
 mixinApply: /@apply[\s]*\([^)]*?\)[\s]*(?:[;\n]|$)?/gim,
 varApply: /[^;:]*?:[^;]*var[^;]*(?:[;\n]|$)?/gim,
 keyframesRule: /^@[^\s]*keyframes/
@@ -2903,7 +3070,7 @@
 }
 },
 rx: {
-VAR_ASSIGN: /(?:^|[;\n]\s*)(--[\w-]*?):\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\n])|$)/gi,
+VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi,
 MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\)/i,
 VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)))[\s]*?\)/gi,
 VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi,
@@ -3287,7 +3454,7 @@
 this._customPrepEffects(archetype);
 archetype._prepBehaviors();
 archetype._prepBindings();
-archetype._notifyPath = this._notifyPathImpl;
+archetype._notifyPathUp = this._notifyPathUpImpl;
 archetype._scopeElementClass = this._scopeElementClassImpl;
 archetype.listen = this._listenImpl;
 archetype._showHideChildren = this._showHideChildrenImpl;
@@ -3425,7 +3592,7 @@
 },
 _forwardInstanceProp: function (inst, prop, value) {
 },
-_notifyPathImpl: function (path, value) {
+_notifyPathUpImpl: function (path, value) {
 var dataHost = this.dataHost;
 var dot = path.indexOf('.');
 var root = dot < 0 ? path : path.slice(0, dot);
@@ -3438,9 +3605,12 @@
 if (this._forwardParentPath) {
 if (path.indexOf(this._parentPropPrefix) === 0) {
 var subPath = path.substring(this._parentPropPrefix.length);
+var model = this._modelForPath(subPath);
+if (model in this._parentProps) {
 this._forwardParentPath(subPath, value);
 }
 }
+}
 Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove);
 },
 _constructorImpl: function (model, host) {
@@ -3543,9 +3713,10 @@
 } else {
 this.pmap[item] = key;
 }
-return key;
+return '#' + key;
 },
 removeKey: function (key) {
+key = this._parseKey(key);
 this._removeFromMap(this.store[key]);
 delete this.store[key];
 },
@@ -3562,16 +3733,29 @@
 return key;
 },
 getKey: function (item) {
+var key;
 if (item && typeof item == 'object') {
-return this.omap.get(item);
+key = this.omap.get(item);
 } else {
-return this.pmap[item];
+key = this.pmap[item];
+}
+if (key != undefined) {
+return '#' + key;
 }
 },
 getKeys: function () {
-return Object.keys(this.store);
+return Object.keys(this.store).map(function (key) {
+return '#' + key;
+});
+},
+_parseKey: function (key) {
+if (key[0] == '#') {
+return key.slice(1);
+}
+throw new Error('unexpected key ' + key);
 },
 setItem: function (key, item) {
+key = this._parseKey(key);
 var old = this.store[key];
 if (old) {
 this._removeFromMap(old);
@@ -3584,6 +3768,7 @@
 this.store[key] = item;
 },
 getItem: function (key) {
+key = this._parseKey(key);
 return this.store[key];
 },
 getItems: function () {
@@ -3977,7 +4162,7 @@
 },
 _forwardInstancePath: function (inst, path, value) {
 if (path.indexOf(this.as + '.') === 0) {
-this.notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value);
+this._notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value);
 }
 },
 _forwardParentProp: function (prop, value) {
@@ -3987,7 +4172,7 @@
 },
 _forwardParentPath: function (path, value) {
 this._instances.forEach(function (inst) {
-inst.notifyPath(path, value, true);
+inst._notifyPath(path, value, true);
 }, this);
 },
 _forwardItemPath: function (path, value) {
@@ -3999,7 +4184,7 @@
 if (inst) {
 if (dot >= 0) {
 path = this.as + '.' + path.substring(dot + 1);
-inst.notifyPath(path, value, true);
+inst._notifyPath(path, value, true);
 } else {
 inst.__setProperty(this.as, value, true);
 }
@@ -4051,6 +4236,7 @@
 }
 } else {
 this.unlinkPaths('selected');
+this.unlinkPaths('selectedItem');
 }
 if (this.multi) {
 if (!this.selected || this.selected.length) {
@@ -4190,7 +4376,7 @@
 },
 _forwardParentPath: function (path, value) {
 if (this._instance) {
-this._instance.notifyPath(path, value, true);
+this._instance._notifyPath(path, value, true);
 }
 }
 });
diff --git a/third_party/polymer/v1_0/components-chromium/polymer/polymer-micro-extracted.js b/third_party/polymer/v1_0/components-chromium/polymer/polymer-micro-extracted.js
index a7f0e4fd..889a234 100644
--- a/third_party/polymer/v1_0/components-chromium/polymer/polymer-micro-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/polymer/polymer-micro-extracted.js
@@ -256,7 +256,7 @@
 function forceDocumentUpgrade() {
 if (cePolyfill) {
 var script = document._currentScript || document.currentScript;
-var doc = script && script.ownerDocument;
+var doc = script && script.ownerDocument || document;
 if (doc) {
 CustomElements.upgradeAll(doc);
 }
@@ -568,7 +568,7 @@
 }
 }
 });
-Polymer.version = '1.1.5';
+Polymer.version = '1.2.1';
 Polymer.Base._addFeature({
 _registerFeatures: function () {
 this._prepIs();
diff --git a/third_party/polymer/v1_0/components-chromium/polymer/polymer-mini-extracted.js b/third_party/polymer/v1_0/components-chromium/polymer/polymer-mini-extracted.js
index 55d8f1a..e1e62f6 100644
--- a/third_party/polymer/v1_0/components-chromium/polymer/polymer-mini-extracted.js
+++ b/third_party/polymer/v1_0/components-chromium/polymer/polymer-mini-extracted.js
@@ -260,61 +260,6 @@
 };
 return new ArraySplice();
 }();
-Polymer.EventApi = function () {
-var Settings = Polymer.Settings;
-var EventApi = function (event) {
-this.event = event;
-};
-if (Settings.useShadow) {
-EventApi.prototype = {
-get rootTarget() {
-return this.event.path[0];
-},
-get localTarget() {
-return this.event.target;
-},
-get path() {
-return this.event.path;
-}
-};
-} else {
-EventApi.prototype = {
-get rootTarget() {
-return this.event.target;
-},
-get localTarget() {
-var current = this.event.currentTarget;
-var currentRoot = current && Polymer.dom(current).getOwnerRoot();
-var p$ = this.path;
-for (var i = 0; i < p$.length; i++) {
-if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {
-return p$[i];
-}
-}
-},
-get path() {
-if (!this.event._path) {
-var path = [];
-var o = this.rootTarget;
-while (o) {
-path.push(o);
-o = Polymer.dom(o).parentNode || o.host;
-}
-path.push(window);
-this.event._path = path;
-}
-return this.event._path;
-}
-};
-}
-var factory = function (event) {
-if (!event.__eventApi) {
-event.__eventApi = new EventApi(event);
-}
-return event.__eventApi;
-};
-return { factory: factory };
-}();
 Polymer.domInnerHTML = function () {
 var escapeAttrRegExp = /[&\u00A0"]/g;
 var escapeDataRegExp = /[&\u00A0<>]/g;
@@ -440,6 +385,17 @@
 flush: function () {
 Polymer.dom.flush();
 },
+deepContains: function (node) {
+if (this.node.contains(node)) {
+return true;
+}
+var n = node;
+var wrappedDocument = wrap(document);
+while (n && n !== wrappedDocument && n !== this.node) {
+n = Polymer.dom(n).parentNode || n.host;
+}
+return n === this.node;
+},
 _lazyDistribute: function (host) {
 if (host.shadyRoot && host.shadyRoot._distributionClean) {
 host.shadyRoot._distributionClean = false;
@@ -453,7 +409,7 @@
 return this._addNode(node, ref_node);
 },
 _addNode: function (node, ref_node) {
-this._removeNodeFromHost(node, true);
+this._removeNodeFromParent(node);
 var addedInsertionPoint;
 var root = this.getOwnerRoot();
 if (root) {
@@ -485,6 +441,7 @@
 if (addedInsertionPoint) {
 this._updateInsertionPoints(root.host);
 }
+this.notifyObserver();
 return node;
 },
 removeChild: function (node) {
@@ -499,6 +456,7 @@
 nativeRemoveChild.call(container, node);
 }
 }
+this.notifyObserver();
 return node;
 },
 replaceChild: function (node, ref_node) {
@@ -591,6 +549,13 @@
 _parentNeedsDistribution: function (parent) {
 return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);
 },
+_removeNodeFromParent: function (node) {
+var parent = node._lightParent || node.parentNode;
+if (parent && hasDomApi(parent)) {
+factory(parent).notifyObserver();
+}
+this._removeNodeFromHost(node, true);
+},
 _removeNodeFromHost: function (node, ensureComposedRemoval) {
 var hostNeedsDist;
 var root;
@@ -602,7 +567,7 @@
 root.host._elementRemove(node);
 hostNeedsDist = this._removeDistributedChildren(root, node);
 }
-this._removeLogicalInfo(node, node._lightParent);
+this._removeLogicalInfo(node, parent);
 }
 this._removeOwnerShadyRoot(node);
 if (root && hostNeedsDist) {
@@ -721,24 +686,29 @@
 return this.node._distributedNodes || [];
 },
 queryDistributedElements: function (selector) {
-var c$ = this.childNodes;
+var c$ = this.getEffectiveChildNodes();
 var list = [];
-this._distributedFilter(selector, c$, list);
 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
-if (c.localName === CONTENT) {
-this._distributedFilter(selector, factory(c).getDistributedNodes(), list);
+if (c.nodeType === Node.ELEMENT_NODE && matchesSelector.call(c, selector)) {
+list.push(c);
 }
 }
 return list;
 },
-_distributedFilter: function (selector, list, results) {
-results = results || [];
-for (var i = 0, l = list.length, d; i < l && (d = list[i]); i++) {
-if (d.nodeType === Node.ELEMENT_NODE && d.localName !== CONTENT && matchesSelector.call(d, selector)) {
-results.push(d);
+getEffectiveChildNodes: function () {
+var list = [];
+var c$ = this.childNodes;
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+if (c.localName === CONTENT) {
+var d$ = factory(c).getDistributedNodes();
+for (var j = 0; j < d$.length; j++) {
+list.push(d$[j]);
+}
+} else {
+list.push(c);
 }
 }
-return results;
+return list;
 },
 _clear: function () {
 while (this.childNodes.length) {
@@ -782,36 +752,24 @@
 }
 }
 return n;
+},
+observeNodes: function (callback) {
+if (callback) {
+if (!this.observer) {
+this.observer = this.node.localName === CONTENT ? new DomApi.DistributedNodesObserver(this) : new DomApi.EffectiveNodesObserver(this);
 }
-};
-Object.defineProperty(DomApi.prototype, 'classList', {
-get: function () {
-if (!this._classList) {
-this._classList = new DomApi.ClassList(this);
+return this.observer.addListener(callback);
 }
-return this._classList;
 },
-configurable: true
-});
-DomApi.ClassList = function (host) {
-this.domApi = host;
-this.node = host.node;
-};
-DomApi.ClassList.prototype = {
-add: function () {
-this.node.classList.add.apply(this.node.classList, arguments);
-this.domApi._distributeParent();
+unobserveNodes: function (handle) {
+if (this.observer) {
+this.observer.removeListener(handle);
+}
 },
-remove: function () {
-this.node.classList.remove.apply(this.node.classList, arguments);
-this.domApi._distributeParent();
-},
-toggle: function () {
-this.node.classList.toggle.apply(this.node.classList, arguments);
-this.domApi._distributeParent();
-},
-contains: function () {
-return this.node.classList.contains.apply(this.node.classList, arguments);
+notifyObserver: function () {
+if (this.observer) {
+this.observer.notify();
+}
 }
 };
 if (!Settings.useShadow) {
@@ -993,6 +951,17 @@
 };
 DomApi.prototype._distributeParent = function () {
 };
+var nativeForwards = [
+'appendChild',
+'insertBefore',
+'removeChild',
+'replaceChild'
+];
+nativeForwards.forEach(function (forward) {
+DomApi.prototype[forward] = function () {
+return this.node[forward].apply(this.node, arguments);
+};
+});
 Object.defineProperties(DomApi.prototype, {
 childNodes: {
 get: function () {
@@ -1046,13 +1015,17 @@
 });
 }
 var CONTENT = 'content';
-var factory = function (node, patch) {
+function factory(node, patch) {
 node = node || document;
 if (!node.__domApi) {
 node.__domApi = new DomApi(node, patch);
 }
 return node.__domApi;
-};
+}
+;
+function hasDomApi(node) {
+return Boolean(node.__domApi);
+}
 Polymer.dom = function (obj, patch) {
 if (obj instanceof Event) {
 return Polymer.EventApi.factory(obj);
@@ -1060,43 +1033,6 @@
 return factory(obj, patch);
 }
 };
-Polymer.Base.extend(Polymer.dom, {
-_flushGuard: 0,
-_FLUSH_MAX: 100,
-_needsTakeRecords: !Polymer.Settings.useNativeCustomElements,
-_debouncers: [],
-_finishDebouncer: null,
-flush: function () {
-for (var i = 0; i < this._debouncers.length; i++) {
-this._debouncers[i].complete();
-}
-if (this._finishDebouncer) {
-this._finishDebouncer.complete();
-}
-this._flushPolyfills();
-if (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {
-this._flushGuard++;
-this.flush();
-} else {
-if (this._flushGuard >= this._FLUSH_MAX) {
-console.warn('Polymer.dom.flush aborted. Flush may not be complete.');
-}
-this._flushGuard = 0;
-}
-},
-_flushPolyfills: function () {
-if (this._needsTakeRecords) {
-CustomElements.takeRecords();
-}
-},
-addDebouncer: function (debouncer) {
-this._debouncers.push(debouncer);
-this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlush);
-},
-_finishFlush: function () {
-Polymer.dom._debouncers = [];
-}
-});
 function getLightChildren(node) {
 var children = node._lightChildren;
 return children ? children : node.childNodes;
@@ -1160,10 +1096,399 @@
 matchesSelector: matchesSelector,
 hasInsertionPoint: hasInsertionPoint,
 ctor: DomApi,
-factory: factory
+factory: factory,
+hasDomApi: hasDomApi
 };
 }();
+Polymer.Base.extend(Polymer.dom, {
+_flushGuard: 0,
+_FLUSH_MAX: 100,
+_needsTakeRecords: !Polymer.Settings.useNativeCustomElements,
+_debouncers: [],
+_staticFlushList: [],
+_finishDebouncer: null,
+flush: function () {
+this._flushGuard = 0;
+this._prepareFlush();
+while (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {
+for (var i = 0; i < this._debouncers.length; i++) {
+this._debouncers[i].complete();
+}
+if (this._finishDebouncer) {
+this._finishDebouncer.complete();
+}
+this._prepareFlush();
+this._flushGuard++;
+}
+if (this._flushGuard >= this._FLUSH_MAX) {
+console.warn('Polymer.dom.flush aborted. Flush may not be complete.');
+}
+},
+_prepareFlush: function () {
+if (this._needsTakeRecords) {
+CustomElements.takeRecords();
+}
+for (var i = 0; i < this._staticFlushList.length; i++) {
+this._staticFlushList[i]();
+}
+},
+addStaticFlush: function (fn) {
+this._staticFlushList.push(fn);
+},
+removeStaticFlush: function (fn) {
+var i = this._staticFlushList.indexOf(fn);
+if (i >= 0) {
+this._staticFlushList.splice(i, 1);
+}
+},
+addDebouncer: function (debouncer) {
+this._debouncers.push(debouncer);
+this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlush);
+},
+_finishFlush: function () {
+Polymer.dom._debouncers = [];
+}
+});
+Polymer.EventApi = function () {
+'use strict';
+var DomApi = Polymer.DomApi.ctor;
+var Settings = Polymer.Settings;
+DomApi.Event = function (event) {
+this.event = event;
+};
+if (Settings.useShadow) {
+DomApi.Event.prototype = {
+get rootTarget() {
+return this.event.path[0];
+},
+get localTarget() {
+return this.event.target;
+},
+get path() {
+return this.event.path;
+}
+};
+} else {
+DomApi.Event.prototype = {
+get rootTarget() {
+return this.event.target;
+},
+get localTarget() {
+var current = this.event.currentTarget;
+var currentRoot = current && Polymer.dom(current).getOwnerRoot();
+var p$ = this.path;
+for (var i = 0; i < p$.length; i++) {
+if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {
+return p$[i];
+}
+}
+},
+get path() {
+if (!this.event._path) {
+var path = [];
+var o = this.rootTarget;
+while (o) {
+path.push(o);
+o = Polymer.dom(o).parentNode || o.host;
+}
+path.push(window);
+this.event._path = path;
+}
+return this.event._path;
+}
+};
+}
+var factory = function (event) {
+if (!event.__eventApi) {
+event.__eventApi = new DomApi.Event(event);
+}
+return event.__eventApi;
+};
+return { factory: factory };
+}();
 (function () {
+'use strict';
+var DomApi = Polymer.DomApi.ctor;
+Object.defineProperty(DomApi.prototype, 'classList', {
+get: function () {
+if (!this._classList) {
+this._classList = new DomApi.ClassList(this);
+}
+return this._classList;
+},
+configurable: true
+});
+DomApi.ClassList = function (host) {
+this.domApi = host;
+this.node = host.node;
+};
+DomApi.ClassList.prototype = {
+add: function () {
+this.node.classList.add.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+},
+remove: function () {
+this.node.classList.remove.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+},
+toggle: function () {
+this.node.classList.toggle.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+},
+contains: function () {
+return this.node.classList.contains.apply(this.node.classList, arguments);
+}
+};
+}());
+(function () {
+'use strict';
+var DomApi = Polymer.DomApi.ctor;
+var Settings = Polymer.Settings;
+var hasDomApi = Polymer.DomApi.hasDomApi;
+DomApi.EffectiveNodesObserver = function (domApi) {
+this.domApi = domApi;
+this.node = this.domApi.node;
+this._listeners = [];
+};
+DomApi.EffectiveNodesObserver.prototype = {
+addListener: function (callback) {
+if (!this._isSetup) {
+this._setup();
+this._isSetup = true;
+}
+var listener = {
+fn: callback,
+_nodes: []
+};
+this._listeners.push(listener);
+this._scheduleNotify();
+return listener;
+},
+removeListener: function (handle) {
+var i = this._listeners.indexOf(handle);
+if (i >= 0) {
+this._listeners.splice(i, 1);
+handle._nodes = [];
+}
+if (!this._hasListeners()) {
+this._cleanup();
+this._isSetup = false;
+}
+},
+_setup: function () {
+this._observeContentElements(this.domApi.childNodes);
+},
+_cleanup: function () {
+this._unobserveContentElements(this.domApi.childNodes);
+},
+_hasListeners: function () {
+return Boolean(this._listeners.length);
+},
+_scheduleNotify: function () {
+if (this._debouncer) {
+this._debouncer.stop();
+}
+this._debouncer = Polymer.Debounce(this._debouncer, this._notify);
+this._debouncer.context = this;
+Polymer.dom.addDebouncer(this._debouncer);
+},
+notify: function () {
+if (this._hasListeners()) {
+this._scheduleNotify();
+}
+},
+_notify: function (mxns) {
+this._beforeCallListeners();
+this._callListeners();
+},
+_beforeCallListeners: function () {
+this._updateContentElements();
+},
+_updateContentElements: function () {
+this._observeContentElements(this.domApi.childNodes);
+},
+_observeContentElements: function (elements) {
+for (var i = 0, n; i < elements.length && (n = elements[i]); i++) {
+if (this._isContent(n)) {
+n.__observeNodesMap = n.__observeNodesMap || new WeakMap();
+if (!n.__observeNodesMap.has(this)) {
+n.__observeNodesMap.set(this, this._observeContent(n));
+}
+}
+}
+},
+_observeContent: function (content) {
+var h = Polymer.dom(content).observeNodes(this._scheduleNotify.bind(this));
+h._avoidChangeCalculation = true;
+return h;
+},
+_unobserveContentElements: function (elements) {
+for (var i = 0, n, h; i < elements.length && (n = elements[i]); i++) {
+if (this._isContent(n)) {
+h = n.__observeNodesMap.get(this);
+if (h) {
+Polymer.dom(n).unobserveNodes(h);
+n.__observeNodesMap.delete(this);
+}
+}
+}
+},
+_isContent: function (node) {
+return node.localName === 'content';
+},
+_callListeners: function () {
+var o$ = this._listeners;
+var nodes = this._getEffectiveNodes();
+for (var i = 0, o; i < o$.length && (o = o$[i]); i++) {
+var info = this._generateListenerInfo(o, nodes);
+if (info || o._alwaysNotify) {
+this._callListener(o, info);
+}
+}
+},
+_getEffectiveNodes: function () {
+return this.domApi.getEffectiveChildNodes();
+},
+_generateListenerInfo: function (listener, newNodes) {
+if (listener._avoidChangeCalculation) {
+return true;
+}
+var oldNodes = listener._nodes;
+var info = {
+target: this.node,
+addedNodes: [],
+removedNodes: []
+};
+var splices = Polymer.ArraySplice.calculateSplices(newNodes, oldNodes);
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {
+info.removedNodes.push(n);
+}
+}
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = s.index; j < s.index + s.addedCount; j++) {
+info.addedNodes.push(newNodes[j]);
+}
+}
+listener._nodes = newNodes;
+if (info.addedNodes.length || info.removedNodes.length) {
+return info;
+}
+},
+_callListener: function (listener, info) {
+return listener.fn.call(this.node, info);
+},
+enableShadowAttributeTracking: function () {
+}
+};
+if (Settings.useShadow) {
+var baseSetup = DomApi.EffectiveNodesObserver.prototype._setup;
+var baseCleanup = DomApi.EffectiveNodesObserver.prototype._cleanup;
+var beforeCallListeners = DomApi.EffectiveNodesObserver.prototype._beforeCallListeners;
+Polymer.Base.extend(DomApi.EffectiveNodesObserver.prototype, {
+_setup: function () {
+if (!this._observer) {
+var self = this;
+this._mutationHandler = function (mxns) {
+if (mxns && mxns.length) {
+self._scheduleNotify();
+}
+};
+this._observer = new MutationObserver(this._mutationHandler);
+this._boundFlush = this._flush.bind(this);
+Polymer.dom.addStaticFlush(this._boundFlush);
+this._observer.observe(this.node, { childList: true });
+}
+baseSetup.call(this);
+},
+_cleanup: function () {
+this._observer.disconnect();
+this._observer = null;
+this._mutationHandler = null;
+Polymer.dom.removeStaticFlush(this._boundFlush);
+baseCleanup.call(this);
+},
+_flush: function () {
+if (this._observer) {
+this._mutationHandler(this._observer.takeRecords());
+}
+},
+enableShadowAttributeTracking: function () {
+if (this._observer) {
+this._makeContentListenersAlwaysNotify();
+this._observer.disconnect();
+this._observer.observe(this.node, {
+childList: true,
+attributes: true,
+subtree: true
+});
+var root = this.domApi.getOwnerRoot();
+var host = root && root.host;
+if (host && Polymer.dom(host).observer) {
+Polymer.dom(host).observer.enableShadowAttributeTracking();
+}
+}
+},
+_makeContentListenersAlwaysNotify: function () {
+for (var i = 0, h; i < this._listeners.length; i++) {
+h = this._listeners[i];
+h._alwaysNotify = h._isContentListener;
+}
+}
+});
+}
+}());
+(function () {
+'use strict';
+var DomApi = Polymer.DomApi.ctor;
+var Settings = Polymer.Settings;
+DomApi.DistributedNodesObserver = function (domApi) {
+DomApi.EffectiveNodesObserver.call(this, domApi);
+};
+DomApi.DistributedNodesObserver.prototype = Object.create(DomApi.EffectiveNodesObserver.prototype);
+Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, {
+_setup: function () {
+},
+_cleanup: function () {
+},
+_beforeCallListeners: function () {
+},
+_getEffectiveNodes: function () {
+return this.domApi.getDistributedNodes();
+}
+});
+if (Settings.useShadow) {
+Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, {
+_setup: function () {
+if (!this._observer) {
+var root = this.domApi.getOwnerRoot();
+var host = root && root.host;
+if (host) {
+this._observer = Polymer.dom(host).observeNodes(this._scheduleNotify.bind(this));
+this._observer._isContentListener = true;
+if (this._hasAttrSelect()) {
+Polymer.dom(host).observer.enableShadowAttributeTracking();
+}
+}
+}
+},
+_hasAttrSelect: function () {
+var select = this.node.getAttribute('select');
+return select && select.match(/[[.]+/);
+},
+_cleanup: function () {
+var root = this.domApi.getOwnerRoot();
+var host = root && root.host;
+if (host) {
+Polymer.dom(host).unobserveNodes(this._observer);
+}
+this._observer = null;
+}
+});
+}
+}());
+(function () {
+var hasDomApi = Polymer.DomApi.hasDomApi;
 Polymer.Base._addFeature({
 _prepShady: function () {
 this._useContent = this._useContent || Boolean(this._template);
@@ -1234,6 +1559,7 @@
 this.shadyRoot._distributionClean = true;
 if (hasInsertionPoint(this.shadyRoot)) {
 this._composeTree();
+notifyContentObservers(this.shadyRoot);
 } else {
 if (!this.shadyRoot._hasDistributed) {
 this.textContent = '';
@@ -1244,6 +1570,9 @@
 this._updateChildNodes(this, children);
 }
 }
+if (!this.shadyRoot._hasDistributed) {
+notifyInitialDistribution(this);
+}
 this.shadyRoot._hasDistributed = true;
 }
 },
@@ -1461,6 +1790,19 @@
 }
 }
 }
+function notifyContentObservers(root) {
+for (var i = 0, c; i < root._insertionPoints.length; i++) {
+c = root._insertionPoints[i];
+if (hasDomApi(c)) {
+Polymer.dom(c).notifyObserver();
+}
+}
+}
+function notifyInitialDistribution(host) {
+if (hasDomApi(host)) {
+Polymer.dom(host).notifyObserver();
+}
+}
 var needsUpgrade = window.CustomElements && !CustomElements.useNative;
 function upgradeLightChildren(children) {
 if (needsUpgrade && children) {
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 1395c531..e9632c6 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -508,9 +508,10 @@
       'win_perf_bisect_builder': 'gyp_official_goma_minimal_symbols_x86',
       'winx64_bisect_builder': 'gyp_official_goma_minimal_symbols_x64',
       'linux_perf_bisect': 'gyp_official_goma',
-      'mac_10_9_perf_bisect': 'gyp_official_goma',
+      'mac_10_11_perf_bisect': 'gyp_official_goma',
       'mac_10_10_perf_bisect': 'gyp_official_goma',
       'mac_retina_perf_bisect': 'gyp_official_goma',
+      'mac_hdd_perf_bisect': 'gyp_official_goma',
       'win_perf_bisect': 'gyp_official_goma_minimal_symbols_x86',
       'win_x64_perf_bisect': 'gyp_official_goma_minimal_symbols_x64',
       'winx64ati_perf_bisect': 'gyp_official_goma_minimal_symbols_x64',
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 74329df3f..2e384b6 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -2196,6 +2196,11 @@
   </details>
 </histogram>
 
+<histogram name="Autofill.FormSubmittedState" enum="AutofillFormSubmittedState">
+  <owner>sebsg@chromium.org</owner>
+  <summary>The autofill state related to a submitted form.</summary>
+</histogram>
+
 <histogram name="Autofill.IsEnabled.PageLoad" enum="BooleanEnabled">
   <owner>isherman@chromium.org</owner>
   <summary>
@@ -36981,11 +36986,27 @@
   </summary>
 </histogram>
 
+<histogram name="Quota.EvictedOriginAccessCount">
+  <owner>calamity@chromium.org</owner>
+  <summary>
+    The number of times the evicted origin was accessed. Logged when the origin
+    is evicted.
+  </summary>
+</histogram>
+
 <histogram name="Quota.EvictedOriginsPerHour">
   <owner>tzik@chromium.org</owner>
   <summary>Number of evicted origins in an hour.</summary>
 </histogram>
 
+<histogram name="Quota.EvictedOriginTimeSinceAccess">
+  <owner>calamity@chromium.org</owner>
+  <summary>
+    The time since the evicted origin was last accessed. Logged when the origin
+    is evicted.
+  </summary>
+</histogram>
+
 <histogram name="Quota.EvictionRoundsPerHour">
   <owner>tzik@chromium.org</owner>
   <summary>Number of eviction rounds in an hour.</summary>
@@ -50564,6 +50585,18 @@
   <summary>HTTP response codes seen by Wallet client.</summary>
 </histogram>
 
+<histogram name="Web.CertVerifyAgreement" enum="WebCertVerifyAgreement">
+  <owner>eugenebut@chromium.com</owner>
+  <summary>
+    [iOS] Reports certificate verification mismatch between SecTrust API and
+    CertVerifier. SecTrust API is used for making load/no-load decision and
+    CertVerifier is used for getting the reason of verification failure. It is
+    expected that mismatches will happen for those 2 approaches (e.g. SecTrust
+    API considers cert as good, but CertVerifier considers same cert as bad).
+    This metric helps to understand how common mismatches are.
+  </summary>
+</histogram>
+
 <histogram name="Webapp.Splashscreen.BackgroundColor"
     enum="SplashscreenColorStatus">
   <owner>mlamouri@chromium.org</owner>
@@ -50606,6 +50639,17 @@
   </summary>
 </histogram>
 
+<histogram name="WebController.CertVerificationErrorsCacheHit"
+    enum="BooleanCacheHit">
+  <owner>eugenebut@chromium.org</owner>
+  <summary>
+    [iOS] Report cache hit/miss for WKWebView cert verification. WKWebView Web
+    Controller has a cache of pending cert verification results to avoid extra
+    verifications when presenting SSL interstitial. This metric helps to
+    understand whether or not cache miss is possible.
+  </summary>
+</histogram>
+
 <histogram name="WebController.ExternalURLRequestBlocking"
     enum="IOSExternalURLRequestStatus">
   <owner>jyquinn@chromium.org</owner>
@@ -52628,6 +52672,28 @@
   </summary>
 </histogram>
 
+<histogram name="WebRTC.Video.SendSideDelayInMs" units="ms">
+  <owner>asapersson@chromium.org</owner>
+  <summary>
+    The average delay (of average delays) of sent packets for a sent video
+    stream. Recorded when a stream is removed. The delay is measured from a
+    frame is input to video engine until a packet is sent to the network. For
+    each sent packet, the average delay of all sent packets over the last second
+    is reported. The average of these reported delays is recorded.
+  </summary>
+</histogram>
+
+<histogram name="WebRTC.Video.SendSideDelayMaxInMs" units="ms">
+  <owner>asapersson@chromium.org</owner>
+  <summary>
+    The average delay (of max delays) of sent packets for a sent video stream.
+    Recorded when a stream is removed. The delay is measured from a frame is
+    input to video engine until a packet is sent to the network. For each sent
+    packet, the maximum delay of all sent packets over the last second is
+    reported. The average of these reported delays is recorded.
+  </summary>
+</histogram>
+
 <histogram name="WebRTC.Video.SentFramesPerSecond" units="fps">
   <owner>asapersson@chromium.org</owner>
   <summary>
@@ -53792,6 +53858,15 @@
              (once)"/>
 </enum>
 
+<enum name="AutofillFormSubmittedState" type="int">
+  <int value="0" label="Non fillable form or new data"/>
+  <int value="1" label="Fillable form, autofilled all"/>
+  <int value="2" label="Fillable form, autofilled some"/>
+  <int value="3" label="Fillable form, autofilled none, did show suggestions"/>
+  <int value="4"
+      label="Fillable form, autofilled none, did not show suggestions"/>
+</enum>
+
 <enum name="AutofillGetRealPanResult" type="int">
   <int value="0" label="Success"/>
   <int value="1" label="Retriable failure"/>
@@ -53935,10 +54010,10 @@
 
 <enum name="AutofillUserHappiness" type="int">
   <int value="0" label="Forms loaded"/>
-  <int value="1" label="Submitted fillable form, autofilled all"/>
-  <int value="2" label="Submitted fillable form, autofilled some"/>
-  <int value="3" label="Submitted fillable form, autofilled none"/>
-  <int value="4" label="Submitted non-fillable form or new data"/>
+  <int value="1" label="Deprecated 1"/>
+  <int value="2" label="Deprecated 2"/>
+  <int value="3" label="Deprecated 3"/>
+  <int value="4" label="Deprecated 4"/>
   <int value="5" label="User did type"/>
   <int value="6" label="Suggestions shown"/>
   <int value="7" label="Suggestions shown (once)"/>
@@ -54325,6 +54400,11 @@
   <int value="1" label="Notification click (within last 5 seconds)"/>
 </enum>
 
+<enum name="BooleanCacheHit" type="int">
+  <int value="0" label="Miss"/>
+  <int value="1" label="Hit"/>
+</enum>
+
 <enum name="BooleanCanCheckUrl" type="int">
   <int value="0" label="Skipped"/>
   <int value="1" label="Can check"/>
@@ -61350,6 +61430,13 @@
   <int value="987" label="DeviceOrientationAbsoluteInsecureOrigin"/>
   <int value="988" label="DeviceOrientationAbsoluteSecureOrigin"/>
   <int value="989" label="FontFaceConstructor"/>
+  <int value="990" label="ServiceWorkerControlledPage"/>
+  <int value="991" label="MeterElementWithContinuousCapacityAppearance"/>
+  <int value="992" label="MeterElementWithDiscreteCapacityAppearance"/>
+  <int value="993" label="MeterElementWithMeterAppearance"/>
+  <int value="994" label="MeterElementWithNoneAppearance"/>
+  <int value="995" label="MeterElementWithRatingAppearance"/>
+  <int value="996" label="MeterElementWithRelevancyAppearance"/>
 </enum>
 
 <enum name="FetchRequestMode" type="int">
@@ -72868,6 +72955,9 @@
   <int value="1" label="Keypress"/>
   <int value="2" label="Mouse"/>
   <int value="3" label="Touch gesture"/>
+  <int value="4" label="Mouse wheel"/>
+  <int value="5" label="Media (foreground tab)"/>
+  <int value="6" label="Media (background tab)"/>
 </enum>
 
 <enum name="SiteIsolationMimeType" type="int">
@@ -75798,6 +75888,13 @@
   <int value="9" label="Chooser cancelled"/>
 </enum>
 
+<enum name="WebCertVerifyAgreement" type="int">
+  <int value="0" label="Accepted by both iOS and NSS."/>
+  <int value="1" label="Rejected by both iOS and NSS."/>
+  <int value="2" label="Accepted only by iOS (rejected by NSS)."/>
+  <int value="3" label="Accepted only by NSS (rejected by iOS)."/>
+</enum>
+
 <enum name="WebFontCacheHit" type="int">
   <int value="0" label="Miss"/>
   <int value="1" label="Hit"/>
diff --git a/tools/perf/benchmarks/benchmark_smoke_unittest.py b/tools/perf/benchmarks/benchmark_smoke_unittest.py
index 06cb011..e8e7bd9c 100644
--- a/tools/perf/benchmarks/benchmark_smoke_unittest.py
+++ b/tools/perf/benchmarks/benchmark_smoke_unittest.py
@@ -83,7 +83,6 @@
     octane,  # Often fails & take long time to timeout on cq bot.
     rasterize_and_record_micro,  # Always fails on cq bot.
     repaint,  # Often fails & takes long time to timeout on cq bot.
-    chrome_signin_startup,  # Failed on linux swarming bot (crbug.com/551236)
     spaceport,  # Takes 451 seconds.
     speedometer,  # Takes 101 seconds.
     jetstream,  # Take 206 seconds.
diff --git a/tools/perf_expectations/perf_expectations.json b/tools/perf_expectations/perf_expectations.json
index 1754751..d61e8bcb 100644
--- a/tools/perf_expectations/perf_expectations.json
+++ b/tools/perf_expectations/perf_expectations.json
@@ -381,7 +381,7 @@
  "linux-release/sizes/nacl_helper_bootstrap/nacl_helper_bootstrap": {"reva": 114822, "revb": 115019, "type": "absolute", "better": "lower", "improve": 8776, "regress": 9700, "sha1": "3f284fed"},
  "linux-release/sizes/totals-textrel/textrel": {"reva": 205083, "revb": 206071, "type": "absolute", "better": "lower", "improve": 1075, "regress": 1189, "sha1": "69d07fda"},
  "mac-release/sizes/Chromium.app/Chromium.app": {"reva": 352327, "revb": 352562, "type": "absolute", "better": "lower", "improve": 161268940, "regress": 164646872, "tolerance": 0.01, "sha1": "c034bb25"},
- "mac-release/sizes/Chromium/Chromium": {"reva": 165473, "revb": 165473, "type": "absolute", "better": "lower", "improve": 8132, "regress": 8988, "sha1": "8e448691"},
+ "mac-release/sizes/Chromium/Chromium": {"reva": 358110, "revb": 358130, "type": "absolute", "better": "lower", "improve": 8819, "regress": 9749, "sha1": "1643612a"},
  "mac-release/sizes/ChromiumFramework/ChromiumFramework": {"reva": 352327, "revb": 352562, "type": "absolute", "better": "lower", "improve": 107868657, "regress": 110093572, "tolerance": 0.01, "sha1": "2fc7a161"},
  "mac-release/sizes/chrome-si/initializers": {"reva": 281731, "revb": 281731, "type": "absolute", "better": "lower", "improve": 0, "regress": 0, "tolerance": 0, "sha1": "01759b7f"},
  "win-release/media_tests_av_perf/audio_latency/latency": {"reva": 199840, "revb": 201303, "type": "absolute", "better": "lower", "improve": 57, "regress": 69, "sha1": "169d47dd"},
diff --git a/tools/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py b/tools/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py
index 77add663..f43578c 100644
--- a/tools/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py
+++ b/tools/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py
@@ -88,7 +88,7 @@
     """
     if len(powermetrics_output) == 0:
       logging.warning('powermetrics produced zero length output')
-      return None
+      return {}
 
     # Container to collect samples for running averages.
     # out_path - list containing the key path in the output dictionary.
@@ -241,13 +241,17 @@
   def _KillPowerMetricsProcess(self):
     """Kill a running powermetrics process."""
     try:
-      self._powermetrics_process.terminate()
-    except OSError:
-      # terminate() can fail when Powermetrics does not have the SetUID set.
-      self._backend.LaunchApplication(
-        '/usr/bin/pkill',
-        ['-SIGTERM', os.path.basename(self.binary_path)],
-        elevate_privilege=True)
+      if self._powermetrics_process.poll() is None:
+        self._powermetrics_process.terminate()
+    except OSError as e:
+      logging.warning(
+          'Error when trying to terminate powermetric process: %s', repr(e))
+      if self._powermetrics_process.poll() is None:
+        # terminate() can fail when Powermetrics does not have the SetUID set.
+        self._backend.LaunchApplication(
+          '/usr/bin/pkill',
+          ['-SIGTERM', os.path.basename(self.binary_path)],
+          elevate_privilege=True)
 
   def StopMonitoringPower(self):
     assert self._powermetrics_process, (
@@ -267,7 +271,10 @@
         powermetrics_output = output_file.read()
       return PowerMetricsPowerMonitor.ParsePowerMetricsOutput(
           powermetrics_output)
-
+    except Exception as e:
+      logging.warning(
+          'Error when trying to collect power monitoring data: %s', repr(e))
+      return PowerMetricsPowerMonitor.ParsePowerMetricsOutput('')
     finally:
       shutil.rmtree(self._output_directory)
       self._output_directory = None
diff --git a/tools/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor_unittest.py b/tools/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor_unittest.py
index 25f5d117..1c5a65ce 100644
--- a/tools/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor_unittest.py
+++ b/tools/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor_unittest.py
@@ -35,7 +35,7 @@
   @decorators.Enabled('mac')
   def testParseEmptyPowerMetricsOutput(self):
     # Important to handle zero length powermetrics outout - crbug.com/353250 .
-    self.assertIsNone(powermetrics_power_monitor.PowerMetricsPowerMonitor.
+    self.assertFalse(powermetrics_power_monitor.PowerMetricsPowerMonitor.
         ParsePowerMetricsOutput(''))
 
   @decorators.Enabled('mac')
diff --git a/tools/valgrind/gtest_exclude/net_unittests.gtest-memcheck.txt b/tools/valgrind/gtest_exclude/net_unittests.gtest-memcheck.txt
index 5114d837..c3a1b6a6 100644
--- a/tools/valgrind/gtest_exclude/net_unittests.gtest-memcheck.txt
+++ b/tools/valgrind/gtest_exclude/net_unittests.gtest-memcheck.txt
@@ -20,3 +20,4 @@
 DiskCacheBackendTest.ShutdownWithPendingCreate_Fast
 DiskCacheBackendTest.ShutdownWithPendingFileIO_Fast
 DiskCacheBackendTest.ShutdownWithPendingIO_Fast
+EndToEndTests/EndToEndTest.*
diff --git a/ui/android/java/src/org/chromium/ui/UiUtils.java b/ui/android/java/src/org/chromium/ui/UiUtils.java
index c164641a..094a354f 100644
--- a/ui/android/java/src/org/chromium/ui/UiUtils.java
+++ b/ui/android/java/src/org/chromium/ui/UiUtils.java
@@ -12,16 +12,22 @@
 import android.os.Build;
 import android.os.Environment;
 import android.os.Handler;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
 
 import org.chromium.base.ContentUriUtils;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -137,6 +143,28 @@
     }
 
     /**
+     * Gets the set of locales supported by the current enabled Input Methods.
+     * @param context A {@link Context} instance.
+     * @return A possibly-empty {@link Set} of locale strings.
+     */
+    public static Set<String> getIMELocales(Context context) {
+        LinkedHashSet<String> locales = new LinkedHashSet<String>();
+        InputMethodManager imManager =
+                (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+        List<InputMethodInfo> enabledMethods = imManager.getEnabledInputMethodList();
+        for (int i = 0; i < enabledMethods.size(); i++) {
+            List<InputMethodSubtype> subtypes =
+                    imManager.getEnabledInputMethodSubtypeList(enabledMethods.get(i), true);
+            if (subtypes == null) continue;
+            for (int j = 0; j < subtypes.size(); j++) {
+                String locale = subtypes.get(j).getLocale();
+                if (!TextUtils.isEmpty(locale)) locales.add(locale);
+            }
+        }
+        return locales;
+    }
+
+    /**
      * Inserts a {@link View} into a {@link ViewGroup} after directly before a given {@View}.
      * @param container The {@link View} to add newView to.
      * @param newView The new {@link View} to add.
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc
index 5d0e73d..88ad086 100644
--- a/ui/aura/window_event_dispatcher.cc
+++ b/ui/aura/window_event_dispatcher.cc
@@ -462,14 +462,20 @@
     }
   }
 
+  DispatchDetails details;
   if (event->IsMouseEvent()) {
-    PreDispatchMouseEvent(target_window, static_cast<ui::MouseEvent*>(event));
+    details = PreDispatchMouseEvent(target_window,
+                                    static_cast<ui::MouseEvent*>(event));
   } else if (event->IsScrollEvent()) {
-    PreDispatchLocatedEvent(target_window,
-                            static_cast<ui::ScrollEvent*>(event));
+    details = PreDispatchLocatedEvent(target_window,
+                                      static_cast<ui::ScrollEvent*>(event));
   } else if (event->IsTouchEvent()) {
-    PreDispatchTouchEvent(target_window, static_cast<ui::TouchEvent*>(event));
+    details = PreDispatchTouchEvent(target_window,
+                                    static_cast<ui::TouchEvent*>(event));
   }
+  if (details.dispatcher_destroyed || details.target_destroyed)
+    return details;
+
   old_dispatch_target_ = event_dispatch_target_;
   event_dispatch_target_ = target_window;
   return DispatchDetails();
@@ -729,8 +735,9 @@
   return OnEventFromSource(&event);
 }
 
-void WindowEventDispatcher::PreDispatchLocatedEvent(Window* target,
-                                                    ui::LocatedEvent* event) {
+DispatchDetails WindowEventDispatcher::PreDispatchLocatedEvent(
+    Window* target,
+    ui::LocatedEvent* event) {
   int flags = event->flags();
   if (IsNonClientLocation(target, event->location()))
     flags |= ui::EF_IS_NON_CLIENT;
@@ -743,10 +750,13 @@
       SetLastMouseLocation(window(), event->root_location());
     synthesize_mouse_move_ = false;
   }
+
+  return DispatchDetails();
 }
 
-void WindowEventDispatcher::PreDispatchMouseEvent(Window* target,
-                                                  ui::MouseEvent* event) {
+DispatchDetails WindowEventDispatcher::PreDispatchMouseEvent(
+    Window* target,
+    ui::MouseEvent* event) {
   client::CursorClient* cursor_client = client::GetCursorClient(window());
   // We allow synthesized mouse exit events through even if mouse events are
   // disabled. This ensures that hover state, etc on controls like buttons is
@@ -756,7 +766,7 @@
       (event->flags() & ui::EF_IS_SYNTHESIZED) &&
       (event->type() != ui::ET_MOUSE_EXITED)) {
     event->SetHandled();
-    return;
+    return DispatchDetails();
   }
 
   if (IsEventCandidateForHold(*event) && !dispatching_held_event_) {
@@ -767,7 +777,7 @@
       }
       held_move_event_.reset(new ui::MouseEvent(*event, target, window()));
       event->SetHandled();
-      return;
+      return DispatchDetails();
     } else {
       // We may have a held event for a period between the time move_hold_count_
       // fell to 0 and the DispatchHeldEvents executes. Since we're going to
@@ -788,7 +798,7 @@
             DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_EXITED);
         if (details.dispatcher_destroyed) {
           event->SetHandled();
-          return;
+          return details;
         }
         mouse_moved_handler_ = NULL;
       }
@@ -803,20 +813,25 @@
         live_window.Add(target);
         DispatchDetails details =
             DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_EXITED);
+        // |details| contains information about |mouse_moved_handler_| being
+        // destroyed which is not our |target|. Return value of this function
+        // should be about our |target|.
+        DispatchDetails target_details = details;
+        target_details.target_destroyed = !live_window.Contains(target);
         if (details.dispatcher_destroyed) {
           event->SetHandled();
-          return;
+          return target_details;
         }
         // If the |mouse_moved_handler_| changes out from under us, assume a
         // nested message loop ran and we don't need to do anything.
         if (mouse_moved_handler_ != old_mouse_moved_handler) {
           event->SetHandled();
-          return;
+          return target_details;
         }
-        if (!live_window.Contains(target) || details.target_destroyed) {
+        if (details.target_destroyed || target_details.target_destroyed) {
           mouse_moved_handler_ = NULL;
           event->SetHandled();
-          return;
+          return target_details;
         }
         live_window.Remove(target);
 
@@ -825,7 +840,7 @@
             DispatchMouseEnterOrExit(target, *event, ui::ET_MOUSE_ENTERED);
         if (details.dispatcher_destroyed || details.target_destroyed) {
           event->SetHandled();
-          return;
+          return details;
         }
       }
       break;
@@ -848,11 +863,12 @@
       break;
   }
 
-  PreDispatchLocatedEvent(target, event);
+  return PreDispatchLocatedEvent(target, event);
 }
 
-void WindowEventDispatcher::PreDispatchTouchEvent(Window* target,
-                                                  ui::TouchEvent* event) {
+DispatchDetails WindowEventDispatcher::PreDispatchTouchEvent(
+    Window* target,
+    ui::TouchEvent* event) {
   switch (event->type()) {
     case ui::ET_TOUCH_PRESSED:
       touch_ids_down_ |= (1 << event->touch_id());
@@ -874,7 +890,7 @@
       if (move_hold_count_ && !dispatching_held_event_) {
         held_move_event_.reset(new ui::TouchEvent(*event, target, window()));
         event->SetHandled();
-        return;
+        return DispatchDetails();
       }
       break;
 
@@ -889,14 +905,14 @@
     // The event is invalid - ignore it.
     event->StopPropagation();
     event->DisableSynchronousHandling();
-    return;
+    return DispatchDetails();
   }
 
   // This flag is set depending on the gestures recognized in the call above,
   // and needs to propagate with the forwarded event.
   event->set_may_cause_scrolling(orig_event.may_cause_scrolling());
 
-  PreDispatchLocatedEvent(target, event);
+  return PreDispatchLocatedEvent(target, event);
 }
 
 }  // namespace aura
diff --git a/ui/aura/window_event_dispatcher.h b/ui/aura/window_event_dispatcher.h
index aa49e81..a44eace1 100644
--- a/ui/aura/window_event_dispatcher.h
+++ b/ui/aura/window_event_dispatcher.h
@@ -234,9 +234,12 @@
   // the mouse cursor.
   void SynthesizeMouseMoveAfterChangeToWindow(Window* window);
 
-  void PreDispatchLocatedEvent(Window* target, ui::LocatedEvent* event);
-  void PreDispatchMouseEvent(Window* target, ui::MouseEvent* event);
-  void PreDispatchTouchEvent(Window* target, ui::TouchEvent* event);
+  ui::EventDispatchDetails PreDispatchLocatedEvent(Window* target,
+                                                   ui::LocatedEvent* event);
+  ui::EventDispatchDetails PreDispatchMouseEvent(Window* target,
+                                                 ui::MouseEvent* event);
+  ui::EventDispatchDetails PreDispatchTouchEvent(Window* target,
+                                                 ui::TouchEvent* event);
 
   WindowTreeHost* host_;
 
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc
index 38c5f2a..f9e80f40 100644
--- a/ui/aura/window_event_dispatcher_unittest.cc
+++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -1535,26 +1535,31 @@
   root_window()->RemovePreTargetHandler(&repost_event_recorder);
 }
 
+// An event filter that deletes the specified object when sees a mouse-exited
+// event.
+template <class T>
 class OnMouseExitDeletingEventFilter : public EventFilterRecorder {
  public:
-  OnMouseExitDeletingEventFilter() : window_to_delete_(NULL) {}
+  explicit OnMouseExitDeletingEventFilter(T* object_to_delete)
+      : object_to_delete_(object_to_delete) {}
+  OnMouseExitDeletingEventFilter() : object_to_delete_(nullptr) {}
   ~OnMouseExitDeletingEventFilter() override {}
 
-  void set_window_to_delete(Window* window_to_delete) {
-    window_to_delete_ = window_to_delete;
+  void set_object_to_delete(T* object_to_delete) {
+    object_to_delete_ = object_to_delete;
   }
 
  private:
-  // Overridden from ui::EventHandler:
+  // Overridden from ui::EventFilterRecorder.
   void OnMouseEvent(ui::MouseEvent* event) override {
     EventFilterRecorder::OnMouseEvent(event);
-    if (window_to_delete_) {
-      delete window_to_delete_;
-      window_to_delete_ = NULL;
+    if (object_to_delete_ && event->type() == ui::ET_MOUSE_EXITED) {
+      delete object_to_delete_;
+      object_to_delete_ = nullptr;
     }
   }
 
-  Window* window_to_delete_;
+  T* object_to_delete_;
 
   DISALLOW_COPY_AND_ASSIGN(OnMouseExitDeletingEventFilter);
 };
@@ -1566,7 +1571,7 @@
   // Create window 1 and set its event filter. Window 1 will take ownership of
   // the event filter.
   scoped_ptr<Window> w1(CreateNormalWindow(1, root_window(), NULL));
-  OnMouseExitDeletingEventFilter w1_filter;
+  OnMouseExitDeletingEventFilter<Window> w1_filter;
   w1->AddPreTargetHandler(&w1_filter);
   w1->SetBounds(gfx::Rect(20, 20, 60, 60));
   EXPECT_EQ(NULL, host()->dispatcher()->mouse_moved_handler());
@@ -1585,9 +1590,9 @@
 
   // Set window 2 as the window that is to be deleted when a mouse-exited event
   // happens on window 1.
-  w1_filter.set_window_to_delete(w2);
+  w1_filter.set_object_to_delete(w2);
 
-  // Move mosue over window 2. This should generate a mouse-exited event for
+  // Move mouse over window 2. This should generate a mouse-exited event for
   // window 1 resulting in deletion of window 2. The original mouse-moved event
   // that was targeted to window 2 should be dropped since window 2 is
   // destroyed. This test passes if no crash happens.
@@ -1599,6 +1604,53 @@
             EventTypesToString(w1_filter.events()));
 }
 
+// Tests the case where the event dispatcher is deleted during the pre-dispatch
+// phase of dispatching and event.
+TEST_F(WindowEventDispatcherTest, DeleteDispatcherDuringPreDispatch) {
+  // Create a host for the window hierarchy. This host will be destroyed later
+  // on.
+  WindowTreeHost* host = WindowTreeHost::Create(gfx::Rect(0, 0, 100, 100));
+  host->InitHost();
+
+  // Create two windows.
+  Window* w1 = CreateNormalWindow(1, host->window(), nullptr);
+  w1->SetBounds(gfx::Rect(20, 20, 60, 60));
+  Window* w2 = CreateNormalWindow(2, host->window(), nullptr);
+  w2->SetBounds(gfx::Rect(80, 20, 120, 60));
+  EXPECT_EQ(nullptr, host->dispatcher()->mouse_moved_handler());
+
+  ui::test::EventGenerator generator(host->window(), w1);
+
+  // Move mouse over window 1 to set it as the |mouse_moved_handler_| for the
+  // root window.
+  generator.MoveMouseTo(40, 40);
+  EXPECT_EQ(w1, host->dispatcher()->mouse_moved_handler());
+
+  // Set appropriate event filters for the two windows with the window tree host
+  // as the object that is to be deleted when a mouse-exited event happens on
+  // window 1. The windows will take ownership of the event filters.
+  OnMouseExitDeletingEventFilter<WindowTreeHost> w1_filter(host);
+  w1->AddPreTargetHandler(&w1_filter);
+  EventFilterRecorder w2_filter;
+  w2->AddPreTargetHandler(&w2_filter);
+
+  // Move mouse over window 2. This should generate a mouse-exited event for
+  // window 1 resulting in deletion of window tree host and its event
+  // dispatcher. The event dispatching should abort since the dispatcher is
+  // destroyed. This test passes if no crash happens.
+  // Here we can't use EventGenerator since it expects that the dispatcher is
+  // not destroyed at the end of the dispatch.
+  ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, gfx::Point(20, 20),
+                            gfx::Point(20, 20), base::TimeDelta(), 0, 0);
+  ui::EventDispatchDetails details =
+      host->dispatcher()->DispatchEvent(w2, &mouse_move);
+  EXPECT_TRUE(details.dispatcher_destroyed);
+
+  // Check events received by the two windows.
+  EXPECT_EQ("MOUSE_EXITED", EventTypesToString(w1_filter.events()));
+  EXPECT_EQ(std::string(), EventTypesToString(w2_filter.events()));
+}
+
 namespace {
 
 // Used to track if OnWindowDestroying() is invoked and if there is a valid
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 31979ab8..286aa74 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -737,8 +737,8 @@
   if (build_ime) {
     sources += [
       "ime/candidate_window_unittest.cc",
+      "ime/composition_text_unittest.cc",
       "ime/chromeos/character_composer_unittest.cc",
-      "ime/chromeos/composition_text_chromeos_unittest.cc",
       "ime/input_method_base_unittest.cc",
       "ime/input_method_chromeos_unittest.cc",
       "ime/remote_input_method_win_unittest.cc",
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn
index 79c8ffb..9169679 100644
--- a/ui/base/ime/BUILD.gn
+++ b/ui/base/ime/BUILD.gn
@@ -14,8 +14,6 @@
     "chromeos/character_composer.h",
     "chromeos/component_extension_ime_manager.cc",
     "chromeos/component_extension_ime_manager.h",
-    "chromeos/composition_text_chromeos.cc",
-    "chromeos/composition_text_chromeos.h",
     "chromeos/extension_ime_util.cc",
     "chromeos/extension_ime_util.h",
     "chromeos/fake_ime_keyboard.cc",
@@ -53,7 +51,9 @@
     "composition_underline.h",
     "ime_bridge.cc",
     "ime_bridge.h",
+    "ime_engine_handler_interface.cc",
     "ime_engine_handler_interface.h",
+    "ime_engine_observer.h",
     "ime_input_context_handler_interface.h",
     "infolist_entry.cc",
     "infolist_entry.h",
diff --git a/ui/base/ime/chromeos/composition_text_chromeos.cc b/ui/base/ime/chromeos/composition_text_chromeos.cc
deleted file mode 100644
index 905d8ea..0000000
--- a/ui/base/ime/chromeos/composition_text_chromeos.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/base/ime/chromeos/composition_text_chromeos.h"
-
-namespace chromeos {
-
-CompositionText::CompositionText()
-  : selection_start_(0),
-    selection_end_(0) {}
-
-CompositionText::~CompositionText() {}
-
-void CompositionText::CopyFrom(const CompositionText& obj) {
-  text_ = obj.text();
-  underline_attributes_ = obj.underline_attributes();
-  selection_start_ = obj.selection_start();
-  selection_end_ = obj.selection_end();
-}
-
-}  // namespace chromeos
diff --git a/ui/base/ime/chromeos/composition_text_chromeos.h b/ui/base/ime/chromeos/composition_text_chromeos.h
deleted file mode 100644
index 3350b0e..0000000
--- a/ui/base/ime/chromeos/composition_text_chromeos.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_BASE_IME_CHROMEOS_COMPOSITION_TEXT_CHROMEOS_H_
-#define UI_BASE_IME_CHROMEOS_COMPOSITION_TEXT_CHROMEOS_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-#include "ui/base/ime/ui_base_ime_export.h"
-
-namespace chromeos {
-
-class UI_BASE_IME_EXPORT CompositionText {
- public:
-  enum UnderlineType {
-    COMPOSITION_TEXT_UNDERLINE_SINGLE = 1,
-    COMPOSITION_TEXT_UNDERLINE_DOUBLE = 2,
-    COMPOSITION_TEXT_UNDERLINE_NONE = 4,
-    COMPOSITION_TEXT_UNDERLINE_ERROR = 8,
-  };
-
-  struct UnderlineAttribute {
-    UnderlineType type;
-    uint32 start_index;  // The inclusive start index.
-    uint32 end_index;  // The exclusive end index.
-  };
-
-  CompositionText();
-  virtual ~CompositionText();
-
-  // Accessors
-  const base::string16& text() const { return text_; }
-  void set_text(const base::string16& text) { text_ = text; }
-
-  const std::vector<UnderlineAttribute>& underline_attributes() const {
-    return underline_attributes_;
-  }
-
-  std::vector<UnderlineAttribute>* mutable_underline_attributes() {
-    return &underline_attributes_;
-  }
-
-  uint32 selection_start() const { return selection_start_; }
-  void set_selection_start(uint32 selection_start) {
-    selection_start_ = selection_start;
-  }
-
-  uint32 selection_end() const { return selection_end_; }
-  void set_selection_end(uint32 selection_end) {
-    selection_end_ = selection_end;
-  }
-
-  void CopyFrom(const CompositionText& obj);
-
- private:
-  base::string16 text_;
-  std::vector<UnderlineAttribute> underline_attributes_;
-  uint32 selection_start_;
-  uint32 selection_end_;
-
-  DISALLOW_COPY_AND_ASSIGN(CompositionText);
-};
-
-}  // namespace chromeos
-
-#endif  // UI_BASE_IME_CHROMEOS_COMPOSITION_TEXT_CHROMEOS_H_
diff --git a/ui/base/ime/chromeos/composition_text_chromeos_unittest.cc b/ui/base/ime/chromeos/composition_text_chromeos_unittest.cc
deleted file mode 100644
index 067681e..0000000
--- a/ui/base/ime/chromeos/composition_text_chromeos_unittest.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-// TODO(nona): Add more tests.
-
-#include "ui/base/ime/chromeos/composition_text_chromeos.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace chromeos {
-
-TEST(CompositionTextTest, CopyTest) {
-  const base::string16 kSampleText = base::UTF8ToUTF16("Sample Text");
-  const CompositionText::UnderlineAttribute kSampleUnderlineAttribute1 = {
-    CompositionText::COMPOSITION_TEXT_UNDERLINE_SINGLE, 10, 20};
-
-  const CompositionText::UnderlineAttribute kSampleUnderlineAttribute2 = {
-    CompositionText::COMPOSITION_TEXT_UNDERLINE_DOUBLE, 11, 21};
-
-  const CompositionText::UnderlineAttribute kSampleUnderlineAttribute3 = {
-    CompositionText::COMPOSITION_TEXT_UNDERLINE_ERROR, 12, 22};
-
-  // Make CompositionText
-  CompositionText text;
-  text.set_text(kSampleText);
-  std::vector<CompositionText::UnderlineAttribute>* underline_attributes =
-      text.mutable_underline_attributes();
-  underline_attributes->push_back(kSampleUnderlineAttribute1);
-  underline_attributes->push_back(kSampleUnderlineAttribute2);
-  underline_attributes->push_back(kSampleUnderlineAttribute3);
-  text.set_selection_start(30);
-  text.set_selection_end(40);
-
-  CompositionText text2;
-  text2.CopyFrom(text);
-
-  EXPECT_EQ(text.text(), text2.text());
-  EXPECT_EQ(text.underline_attributes().size(),
-            text2.underline_attributes().size());
-  for (size_t i = 0; i < text.underline_attributes().size(); ++i) {
-    EXPECT_EQ(text.underline_attributes()[i].type,
-              text2.underline_attributes()[i].type);
-    EXPECT_EQ(text.underline_attributes()[i].start_index,
-              text2.underline_attributes()[i].start_index);
-    EXPECT_EQ(text.underline_attributes()[i].end_index,
-              text2.underline_attributes()[i].end_index);
-  }
-
-  EXPECT_EQ(text.selection_start(), text2.selection_start());
-  EXPECT_EQ(text.selection_end(), text2.selection_end());
-}
-
-}  // namespace chromeos
diff --git a/ui/base/ime/chromeos/input_method_manager.h b/ui/base/ime/chromeos/input_method_manager.h
index 0b903dfd..2f992ce 100644
--- a/ui/base/ime/chromeos/input_method_manager.h
+++ b/ui/base/ime/chromeos/input_method_manager.h
@@ -18,6 +18,7 @@
 
 namespace ui {
 class Accelerator;
+class IMEEngineHandlerInterface;
 }  // namespace ui
 
 namespace user_manager {
@@ -26,7 +27,6 @@
 
 namespace chromeos {
 class ComponentExtensionIMEManager;
-class InputMethodEngineInterface;
 namespace input_method {
 class InputMethodUtil;
 class ImeKeyboard;
@@ -77,7 +77,7 @@
     virtual void AddInputMethodExtension(
         const std::string& extension_id,
         const InputMethodDescriptors& descriptors,
-        InputMethodEngineInterface* instance) = 0;
+        ui::IMEEngineHandlerInterface* instance) = 0;
 
     // Removes an input method extension.
     virtual void RemoveInputMethodExtension(
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.cc b/ui/base/ime/chromeos/mock_ime_engine_handler.cc
index 3455b65a..49dd4d4 100644
--- a/ui/base/ime/chromeos/mock_ime_engine_handler.cc
+++ b/ui/base/ime/chromeos/mock_ime_engine_handler.cc
@@ -53,9 +53,8 @@
   return true;
 }
 
-void MockIMEEngineHandler::ProcessKeyEvent(
-    const ui::KeyEvent& key_event,
-    const KeyEventDoneCallback& callback) {
+void MockIMEEngineHandler::ProcessKeyEvent(const ui::KeyEvent& key_event,
+                                           KeyEventDoneCallback& callback) {
   ++process_key_event_call_count_;
   last_processed_key_event_.reset(new ui::KeyEvent(key_event));
   last_passed_callback_ = callback;
@@ -78,4 +77,78 @@
     const std::vector<gfx::Rect>& bounds) {
 }
 
+bool MockIMEEngineHandler::SetComposition(
+    int context_id,
+    const char* text,
+    int selection_start,
+    int selection_end,
+    int cursor,
+    const std::vector<SegmentInfo>& segments,
+    std::string* error) {
+  return false;
+}
+
+bool MockIMEEngineHandler::ClearComposition(int context_id,
+                                            std::string* error) {
+  return false;
+}
+
+bool MockIMEEngineHandler::CommitText(int context_id,
+                                      const char* text,
+                                      std::string* error) {
+  return false;
+}
+
+bool MockIMEEngineHandler::SendKeyEvents(
+    int context_id,
+    const std::vector<KeyboardEvent>& events) {
+  return false;
+}
+
+bool MockIMEEngineHandler::IsActive() const {
+  return false;
+}
+
+const std::string& MockIMEEngineHandler::GetActiveComponentId() const {
+  return active_component_id_;
+}
+
+bool MockIMEEngineHandler::DeleteSurroundingText(int context_id,
+                                                 int offset,
+                                                 size_t number_of_chars,
+                                                 std::string* error) {
+  return false;
+}
+
+const MockIMEEngineHandler::CandidateWindowProperty&
+MockIMEEngineHandler::GetCandidateWindowProperty() const {
+  return candidate_window_property_;
+}
+
+bool MockIMEEngineHandler::SetCandidateWindowVisible(bool visible,
+                                                     std::string* error) {
+  return false;
+}
+
+bool MockIMEEngineHandler::SetCandidates(
+    int context_id,
+    const std::vector<Candidate>& candidates,
+    std::string* error) {
+  return false;
+}
+
+bool MockIMEEngineHandler::SetCursorPosition(int context_id,
+                                             int candidate_id,
+                                             std::string* error) {
+  return false;
+}
+
+bool MockIMEEngineHandler::SetMenuItems(const std::vector<MenuItem>& items) {
+  return false;
+}
+
+bool MockIMEEngineHandler::UpdateMenuItems(const std::vector<MenuItem>& items) {
+  return false;
+}
+
 } // namespace chromeos
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.h b/ui/base/ime/chromeos/mock_ime_engine_handler.h
index 539c98f..d212fc5 100644
--- a/ui/base/ime/chromeos/mock_ime_engine_handler.h
+++ b/ui/base/ime/chromeos/mock_ime_engine_handler.h
@@ -25,7 +25,7 @@
   void Reset() override;
   bool IsInterestedInKeyEvent() const override;
   void ProcessKeyEvent(const ui::KeyEvent& key_event,
-                       const KeyEventDoneCallback& callback) override;
+                       KeyEventDoneCallback& callback) override;
   void CandidateClicked(uint32 index) override;
   void SetSurroundingText(const std::string& text,
                           uint32 cursor_pos,
@@ -71,6 +71,53 @@
     return last_passed_callback_;
   }
 
+  bool SetComposition(int context_id,
+                      const char* text,
+                      int selection_start,
+                      int selection_end,
+                      int cursor,
+                      const std::vector<SegmentInfo>& segments,
+                      std::string* error) override;
+
+  bool ClearComposition(int context_id, std::string* error) override;
+
+  bool CommitText(int context_id,
+                  const char* text,
+                  std::string* error) override;
+
+  bool SendKeyEvents(int context_id,
+                     const std::vector<KeyboardEvent>& events) override;
+
+  bool IsActive() const override;
+
+  const std::string& GetActiveComponentId() const override;
+
+  bool DeleteSurroundingText(int context_id,
+                             int offset,
+                             size_t number_of_chars,
+                             std::string* error) override;
+
+  const CandidateWindowProperty& GetCandidateWindowProperty() const override;
+
+  void SetCandidateWindowProperty(
+      const CandidateWindowProperty& property) override {}
+
+  bool SetCandidateWindowVisible(bool visible, std::string* error) override;
+
+  bool SetCandidates(int context_id,
+                     const std::vector<Candidate>& candidates,
+                     std::string* error) override;
+
+  bool SetCursorPosition(int context_id,
+                         int candidate_id,
+                         std::string* error) override;
+
+  bool SetMenuItems(const std::vector<MenuItem>& items) override;
+
+  bool UpdateMenuItems(const std::vector<MenuItem>& items) override;
+
+  void HideInputView() override {}
+
  private:
   int focus_in_call_count_;
   int focus_out_call_count_;
@@ -84,6 +131,8 @@
   uint32 last_set_surrounding_anchor_pos_;
   scoped_ptr<ui::KeyEvent> last_processed_key_event_;
   KeyEventDoneCallback last_passed_callback_;
+  std::string active_component_id_;
+  CandidateWindowProperty candidate_window_property_;
 };
 
 }  // namespace chromeos
diff --git a/ui/base/ime/chromeos/mock_ime_input_context_handler.cc b/ui/base/ime/chromeos/mock_ime_input_context_handler.cc
index 936caf22..c139e705 100644
--- a/ui/base/ime/chromeos/mock_ime_input_context_handler.cc
+++ b/ui/base/ime/chromeos/mock_ime_input_context_handler.cc
@@ -4,7 +4,7 @@
 
 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
 
-#include "ui/base/ime/chromeos/composition_text_chromeos.h"
+#include "ui/base/ime/composition_text.h"
 
 namespace chromeos {
 
@@ -23,7 +23,7 @@
 }
 
 void MockIMEInputContextHandler::UpdateCompositionText(
-    const CompositionText& text,
+    const ui::CompositionText& text,
     uint32 cursor_pos,
     bool visible) {
   ++update_preedit_text_call_count_;
diff --git a/ui/base/ime/chromeos/mock_ime_input_context_handler.h b/ui/base/ime/chromeos/mock_ime_input_context_handler.h
index ceb8b8f4..21fa313 100644
--- a/ui/base/ime/chromeos/mock_ime_input_context_handler.h
+++ b/ui/base/ime/chromeos/mock_ime_input_context_handler.h
@@ -5,7 +5,7 @@
 #ifndef UI_BASE_IME_CHROMEOS_MOCK_IME_INPUT_CONTEXT_HANDLER_H_
 #define UI_BASE_IME_CHROMEOS_MOCK_IME_INPUT_CONTEXT_HANDLER_H_
 
-#include "ui/base/ime/chromeos/composition_text_chromeos.h"
+#include "ui/base/ime/composition_text.h"
 #include "ui/base/ime/ime_input_context_handler_interface.h"
 #include "ui/base/ime/ui_base_ime_export.h"
 
@@ -15,7 +15,7 @@
     : public ui::IMEInputContextHandlerInterface {
  public:
   struct UpdateCompositionTextArg {
-    CompositionText composition_text;
+    ui::CompositionText composition_text;
     uint32 cursor_pos;
     bool is_visible;
   };
@@ -29,7 +29,7 @@
   virtual ~MockIMEInputContextHandler();
 
   void CommitText(const std::string& text) override;
-  void UpdateCompositionText(const CompositionText& text,
+  void UpdateCompositionText(const ui::CompositionText& text,
                              uint32 cursor_pos,
                              bool visible) override;
   void DeleteSurroundingText(int32 offset, uint32 length) override;
diff --git a/ui/base/ime/composition_text.cc b/ui/base/ime/composition_text.cc
index f85bc748..d3ae7f3 100644
--- a/ui/base/ime/composition_text.cc
+++ b/ui/base/ime/composition_text.cc
@@ -18,4 +18,13 @@
   selection = gfx::Range();
 }
 
+void CompositionText::CopyFrom(const CompositionText& obj) {
+  Clear();
+  text = obj.text;
+  for (size_t i = 0; i < obj.underlines.size(); i++) {
+    underlines.push_back(obj.underlines[i]);
+  }
+  selection = obj.selection;
+}
+
 }  // namespace ui
diff --git a/ui/base/ime/composition_text.h b/ui/base/ime/composition_text.h
index 063592e..f5b1e37 100644
--- a/ui/base/ime/composition_text.h
+++ b/ui/base/ime/composition_text.h
@@ -35,6 +35,8 @@
 
   void Clear();
 
+  void CopyFrom(const CompositionText& obj);
+
   // Content of the composition text.
   base::string16 text;
 
diff --git a/ui/base/ime/composition_text_unittest.cc b/ui/base/ime/composition_text_unittest.cc
new file mode 100644
index 0000000..d7ed2b8
--- /dev/null
+++ b/ui/base/ime/composition_text_unittest.cc
@@ -0,0 +1,51 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/ime/composition_text.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ui {
+
+TEST(CompositionTextTest, CopyTest) {
+  const base::string16 kSampleText = base::UTF8ToUTF16("Sample Text");
+  const CompositionUnderline kSampleUnderline1(10, 20, SK_ColorBLACK, false,
+                                               SK_ColorTRANSPARENT);
+
+  const CompositionUnderline kSampleUnderline2(11, 21, SK_ColorBLACK, true,
+                                               SK_ColorTRANSPARENT);
+
+  const CompositionUnderline kSampleUnderline3(12, 22, SK_ColorRED, false,
+                                               SK_ColorTRANSPARENT);
+
+  // Make CompositionText
+  CompositionText text;
+  text.text = kSampleText;
+  text.underlines.push_back(kSampleUnderline1);
+  text.underlines.push_back(kSampleUnderline2);
+  text.underlines.push_back(kSampleUnderline3);
+  text.selection.set_start(30);
+  text.selection.set_end(40);
+
+  CompositionText text2;
+  text2.CopyFrom(text);
+
+  EXPECT_EQ(text.text, text2.text);
+  EXPECT_EQ(text.underlines.size(), text2.underlines.size());
+  for (size_t i = 0; i < text.underlines.size(); ++i) {
+    EXPECT_EQ(text.underlines[i].start_offset,
+              text2.underlines[i].start_offset);
+    EXPECT_EQ(text.underlines[i].end_offset, text2.underlines[i].end_offset);
+    EXPECT_EQ(text.underlines[i].color, text2.underlines[i].color);
+    EXPECT_EQ(text.underlines[i].thick, text2.underlines[i].thick);
+    EXPECT_EQ(text.underlines[i].background_color,
+              text2.underlines[i].background_color);
+  }
+
+  EXPECT_EQ(text.selection.start(), text2.selection.start());
+  EXPECT_EQ(text.selection.end(), text2.selection.end());
+}
+
+}  // namespace ui
diff --git a/ui/base/ime/ime_engine_handler_interface.cc b/ui/base/ime/ime_engine_handler_interface.cc
new file mode 100644
index 0000000..ac45526
--- /dev/null
+++ b/ui/base/ime/ime_engine_handler_interface.cc
@@ -0,0 +1,43 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/ime/ime_engine_handler_interface.h"
+
+namespace ui {
+
+IMEEngineHandlerInterface::KeyboardEvent::KeyboardEvent()
+    : alt_key(false), ctrl_key(false), shift_key(false), caps_lock(false) {}
+
+IMEEngineHandlerInterface::KeyboardEvent::~KeyboardEvent() {}
+
+// ChromeOS only APIs.
+#if defined(OS_CHROMEOS)
+
+IMEEngineHandlerInterface::MenuItem::MenuItem() {}
+
+IMEEngineHandlerInterface::MenuItem::~MenuItem() {}
+
+IMEEngineHandlerInterface::Candidate::Candidate() {}
+
+IMEEngineHandlerInterface::Candidate::~Candidate() {}
+
+namespace {
+// The default entry number of a page in CandidateWindowProperty.
+const int kDefaultPageSize = 9;
+}  // namespace
+
+// When the default values are changed, please modify
+// CandidateWindow::CandidateWindowProperty defined in chromeos/ime/ too.
+IMEEngineHandlerInterface::CandidateWindowProperty::CandidateWindowProperty()
+    : page_size(kDefaultPageSize),
+      is_cursor_visible(true),
+      is_vertical(false),
+      show_window_at_composition(false) {}
+
+IMEEngineHandlerInterface::CandidateWindowProperty::~CandidateWindowProperty() {
+}
+
+#endif
+
+}  // namespace ui
diff --git a/ui/base/ime/ime_engine_handler_interface.h b/ui/base/ime/ime_engine_handler_interface.h
index 04a6beac6..9a27873 100644
--- a/ui/base/ime/ime_engine_handler_interface.h
+++ b/ui/base/ime/ime_engine_handler_interface.h
@@ -30,9 +30,13 @@
   // A type of each member is based on the html spec, but InputContext can be
   // used to specify about a non html text field like Omnibox.
   struct InputContext {
+    InputContext() {}
     InputContext(TextInputType type_, TextInputMode mode_, int flags_)
         : type(type_), mode(mode_), flags(flags_) {}
-
+    InputContext(int id_, TextInputType type_, TextInputMode mode_, int flags_)
+        : id(id_), type(type_), mode(mode_), flags(flags_) {}
+    // An attribute of the context id which used for ChromeOS only.
+    int id;
     // An attribute of the field defined at
     // http://www.w3.org/TR/html401/interact/forms.html#input-control-types.
     TextInputType type;
@@ -46,6 +50,33 @@
     int flags;
   };
 
+  struct KeyboardEvent {
+    KeyboardEvent();
+    virtual ~KeyboardEvent();
+
+    std::string type;
+    std::string key;
+    std::string code;
+    int key_code;  // only used by on-screen keyboards.
+    std::string extension_id;
+    bool alt_key;
+    bool ctrl_key;
+    bool shift_key;
+    bool caps_lock;
+  };
+
+  enum SegmentStyle {
+    SEGMENT_STYLE_UNDERLINE,
+    SEGMENT_STYLE_DOUBLE_UNDERLINE,
+    SEGMENT_STYLE_NO_UNDERLINE,
+  };
+
+  struct SegmentInfo {
+    int start;
+    int end;
+    SegmentStyle style;
+  };
+
   virtual ~IMEEngineHandlerInterface() {}
 
   // Called when the Chrome input field get the focus.
@@ -69,11 +100,7 @@
   // Called when the key event is received.
   // Actual implementation must call |callback| after key event handling.
   virtual void ProcessKeyEvent(const KeyEvent& key_event,
-                               const KeyEventDoneCallback& callback) = 0;
-
-  // Called when the candidate in lookup table is clicked. The |index| is 0
-  // based candidate index in lookup table.
-  virtual void CandidateClicked(uint32 index) = 0;
+                               KeyEventDoneCallback& callback) = 0;
 
   // Called when a new surrounding text is set. The |text| is surrounding text
   // and |cursor_pos| is 0 based index of cursor position in |text|. If there is
@@ -92,6 +119,155 @@
   // If not, InputMethodChromeOS won't feed it with key events.
   virtual bool IsInterestedInKeyEvent() const = 0;
 
+  // Set the current composition and associated properties.
+  virtual bool SetComposition(int context_id,
+                              const char* text,
+                              int selection_start,
+                              int selection_end,
+                              int cursor,
+                              const std::vector<SegmentInfo>& segments,
+                              std::string* error) = 0;
+
+  // Clear the current composition.
+  virtual bool ClearComposition(int context_id, std::string* error) = 0;
+
+  // Commit the specified text to the specified context.  Fails if the context
+  // is not focused.
+  virtual bool CommitText(int context_id,
+                          const char* text,
+                          std::string* error) = 0;
+
+  // Send the sequence of key events.
+  virtual bool SendKeyEvents(int context_id,
+                             const std::vector<KeyboardEvent>& events) = 0;
+
+  // Returns true if this IME is active, false if not.
+  virtual bool IsActive() const = 0;
+
+  // Returns the current active input_component id.
+  virtual const std::string& GetActiveComponentId() const = 0;
+
+  // Deletes |number_of_chars| unicode characters as the basis of |offset| from
+  // the surrounding text. The |offset| is relative position based on current
+  // caret.
+  // NOTE: Currently we are falling back to backspace forwarding workaround,
+  // because delete_surrounding_text is not supported in Chrome. So this
+  // function is restricted for only preceding text.
+  // TODO(nona): Support full spec delete surrounding text.
+  virtual bool DeleteSurroundingText(int context_id,
+                                     int offset,
+                                     size_t number_of_chars,
+                                     std::string* error) = 0;
+
+// ChromeOS only APIs.
+#if defined(OS_CHROMEOS)
+
+  enum {
+    MENU_ITEM_MODIFIED_LABEL = 0x0001,
+    MENU_ITEM_MODIFIED_STYLE = 0x0002,
+    MENU_ITEM_MODIFIED_VISIBLE = 0x0004,
+    MENU_ITEM_MODIFIED_ENABLED = 0x0008,
+    MENU_ITEM_MODIFIED_CHECKED = 0x0010,
+    MENU_ITEM_MODIFIED_ICON = 0x0020,
+  };
+
+  enum MenuItemStyle {
+    MENU_ITEM_STYLE_NONE,
+    MENU_ITEM_STYLE_CHECK,
+    MENU_ITEM_STYLE_RADIO,
+    MENU_ITEM_STYLE_SEPARATOR,
+  };
+
+  enum CandidateWindowPosition {
+    WINDOW_POS_CURSOR,
+    WINDOW_POS_COMPOSITTION,
+  };
+
+  struct MenuItem {
+    MenuItem();
+    virtual ~MenuItem();
+
+    std::string id;
+    std::string label;
+    MenuItemStyle style;
+    bool visible;
+    bool enabled;
+    bool checked;
+
+    unsigned int modified;
+    std::vector<MenuItem> children;
+  };
+
+  struct UsageEntry {
+    std::string title;
+    std::string body;
+  };
+
+  struct Candidate {
+    Candidate();
+    virtual ~Candidate();
+
+    std::string value;
+    int id;
+    std::string label;
+    std::string annotation;
+    UsageEntry usage;
+    std::vector<Candidate> candidates;
+  };
+
+  struct CandidateWindowProperty {
+    CandidateWindowProperty();
+    virtual ~CandidateWindowProperty();
+    int page_size;
+    bool is_cursor_visible;
+    bool is_vertical;
+    bool show_window_at_composition;
+
+    // Auxiliary text is typically displayed in the footer of the candidate
+    // window.
+    std::string auxiliary_text;
+    bool is_auxiliary_text_visible;
+  };
+
+  // Called when the candidate in lookup table is clicked. The |index| is 0
+  // based candidate index in lookup table.
+  virtual void CandidateClicked(uint32 index) = 0;
+
+  // This function returns the current property of the candidate window.
+  // The caller can use the returned value as the default property and
+  // modify some of specified items.
+  virtual const CandidateWindowProperty& GetCandidateWindowProperty() const = 0;
+
+  // Change the property of the candidate window and repaint the candidate
+  // window widget.
+  virtual void SetCandidateWindowProperty(
+      const CandidateWindowProperty& property) = 0;
+
+  // Show or hide the candidate window.
+  virtual bool SetCandidateWindowVisible(bool visible, std::string* error) = 0;
+
+  // Set the list of entries displayed in the candidate window.
+  virtual bool SetCandidates(int context_id,
+                             const std::vector<Candidate>& candidates,
+                             std::string* error) = 0;
+
+  // Set the position of the cursor in the candidate window.
+  virtual bool SetCursorPosition(int context_id,
+                                 int candidate_id,
+                                 std::string* error) = 0;
+
+  // Set the list of items that appears in the language menu when this IME is
+  // active.
+  virtual bool SetMenuItems(const std::vector<MenuItem>& items) = 0;
+
+  // Update the state of the menu items.
+  virtual bool UpdateMenuItems(const std::vector<MenuItem>& items) = 0;
+
+  // Hides the input view window (from API call).
+  virtual void HideInputView() = 0;
+
+#endif
+
  protected:
   IMEEngineHandlerInterface() {}
 };
diff --git a/ui/base/ime/ime_engine_observer.h b/ui/base/ime/ime_engine_observer.h
new file mode 100644
index 0000000..39ded6c42
--- /dev/null
+++ b/ui/base/ime/ime_engine_observer.h
@@ -0,0 +1,78 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_BASE_IME_IME_ENGINE_OBSERVER_H_
+#define UI_BASE_IME_IME_ENGINE_OBSERVER_H_
+
+#include "ui/base/ime/ime_engine_handler_interface.h"
+
+namespace ui {
+
+class IMEEngineObserver {
+ public:
+  virtual ~IMEEngineObserver() {}
+
+  // Called when a text field gains focus, and will be sending key events.
+  virtual void OnFocus(
+      const IMEEngineHandlerInterface::InputContext& context) = 0;
+
+  // Called when a text field loses focus, and will no longer generate events.
+  virtual void OnBlur(int context_id) = 0;
+
+  // Called when the user pressed a key with a text field focused.
+  virtual void OnKeyEvent(
+      const std::string& engine_id,
+      const IMEEngineHandlerInterface::KeyboardEvent& event,
+      IMEEngineHandlerInterface::KeyEventDoneCallback& key_data) = 0;
+
+  // Called when Chrome terminates on-going text input session.
+  virtual void OnReset(const std::string& engine_id) = 0;
+
+  // Called when the IME is no longer active.
+  virtual void OnDeactivated(const std::string& engine_id) = 0;
+
+  // Called when composition bounds are changed.
+  virtual void OnCompositionBoundsChanged(
+      const std::vector<gfx::Rect>& bounds) = 0;
+
+// ChromeOS only APIs.
+#if defined(OS_CHROMEOS)
+
+  enum MouseButtonEvent {
+    MOUSE_BUTTON_LEFT,
+    MOUSE_BUTTON_RIGHT,
+    MOUSE_BUTTON_MIDDLE,
+  };
+
+  // Called when the IME becomes the active IME.
+  virtual void OnActivate(const std::string& engine_id) = 0;
+
+  // Called when an InputContext's properties change while it is focused.
+  virtual void OnInputContextUpdate(
+      const IMEEngineHandlerInterface::InputContext& context) = 0;
+
+  // Returns whether the observer is interested in key events.
+  virtual bool IsInterestedInKeyEvent() const = 0;
+
+  // Called when the user clicks on an item in the candidate list.
+  virtual void OnCandidateClicked(const std::string& engine_id,
+                                  int candidate_id,
+                                  MouseButtonEvent button) = 0;
+
+  // Called when a menu item for this IME is interacted with.
+  virtual void OnMenuItemActivated(const std::string& engine_id,
+                                   const std::string& menu_id) = 0;
+
+  // Called when a surrounding text is changed.
+  virtual void OnSurroundingTextChanged(const std::string& engine_id,
+                                        const std::string& text,
+                                        int cursor_pos,
+                                        int anchor_pos,
+                                        int offset_pos) = 0;
+#endif
+};
+
+}  // namespace ui
+
+#endif  // UI_BASE_IME_IME_ENGINE_OBSERVER_H_
diff --git a/ui/base/ime/ime_input_context_handler_interface.h b/ui/base/ime/ime_input_context_handler_interface.h
index efb0fbe..f5520f52 100644
--- a/ui/base/ime/ime_input_context_handler_interface.h
+++ b/ui/base/ime/ime_input_context_handler_interface.h
@@ -7,12 +7,9 @@
 
 #include <string>
 #include "base/basictypes.h"
+#include "ui/base/ime/composition_text.h"
 #include "ui/base/ime/ui_base_ime_export.h"
 
-namespace chromeos {
-class CompositionText;
-}
-
 namespace ui {
 
 class UI_BASE_IME_EXPORT IMEInputContextHandlerInterface {
@@ -21,7 +18,7 @@
   virtual void CommitText(const std::string& text) = 0;
 
   // Called when the engine updates composition text.
-  virtual void UpdateCompositionText(const chromeos::CompositionText& text,
+  virtual void UpdateCompositionText(const CompositionText& text,
                                      uint32 cursor_pos,
                                      bool visible) = 0;
 
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc
index 96ff2ad..fc5b3a1 100644
--- a/ui/base/ime/input_method_chromeos.cc
+++ b/ui/base/ime/input_method_chromeos.cc
@@ -17,9 +17,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/sys_info.h"
 #include "base/third_party/icu/icu_utf.h"
-#include "ui/base/ime/chromeos/composition_text_chromeos.h"
 #include "ui/base/ime/chromeos/ime_keyboard.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
+#include "ui/base/ime/composition_text.h"
 #include "ui/base/ime/ime_bridge.h"
 #include "ui/base/ime/ime_engine_handler_interface.h"
 #include "ui/base/ime/text_input_client.h"
@@ -138,12 +138,12 @@
 
   handling_key_event_ = true;
   if (GetEngine()->IsInterestedInKeyEvent()) {
-    GetEngine()->ProcessKeyEvent(
-        *event,
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback =
         base::Bind(&InputMethodChromeOS::ProcessKeyEventDone,
                    weak_ptr_factory_.GetWeakPtr(),
                    // Pass the ownership of the new copied event.
-                   base::Owned(new ui::KeyEvent(*event))));
+                   base::Owned(new ui::KeyEvent(*event)));
+    GetEngine()->ProcessKeyEvent(*event, callback);
   } else {
     ProcessKeyEventDone(event, false);
   }
@@ -499,10 +499,9 @@
   }
 }
 
-void InputMethodChromeOS::UpdateCompositionText(
-    const chromeos::CompositionText& text,
-    uint32 cursor_pos,
-    bool visible) {
+void InputMethodChromeOS::UpdateCompositionText(const CompositionText& text,
+                                                uint32 cursor_pos,
+                                                bool visible) {
   if (IsTextInputTypeNone())
     return;
 
@@ -510,7 +509,7 @@
     chromeos::IMECandidateWindowHandlerInterface* candidate_window =
         ui::IMEBridge::Get()->GetCandidateWindowHandler();
     if (candidate_window)
-      candidate_window->UpdatePreeditText(text.text(), cursor_pos, visible);
+      candidate_window->UpdatePreeditText(text.text, cursor_pos, visible);
   }
 
   // |visible| argument is very confusing. For example, what's the correct
@@ -578,10 +577,9 @@
     return false;
 
   // CharacterComposer consumed the key event.  Update the composition text.
-  chromeos::CompositionText preedit;
-  preedit.set_text(character_composer_.preedit_string());
-  UpdateCompositionText(preedit, preedit.text().size(),
-                        !preedit.text().empty());
+  CompositionText preedit;
+  preedit.text = character_composer_.preedit_string();
+  UpdateCompositionText(preedit, preedit.text.size(), !preedit.text.empty());
   std::string commit_text =
       base::UTF16ToUTF8(character_composer_.composed_character());
   if (!commit_text.empty()) {
@@ -591,11 +589,11 @@
 }
 
 void InputMethodChromeOS::ExtractCompositionText(
-    const chromeos::CompositionText& text,
+    const CompositionText& text,
     uint32 cursor_position,
     CompositionText* out_composition) const {
   out_composition->Clear();
-  out_composition->text = text.text();
+  out_composition->text = text.text;
 
   if (out_composition->text.empty())
     return;
@@ -619,36 +617,24 @@
 
   out_composition->selection = gfx::Range(cursor_offset);
 
-  const std::vector<chromeos::CompositionText::UnderlineAttribute>&
-      underline_attributes = text.underline_attributes();
-  if (!underline_attributes.empty()) {
-    for (size_t i = 0; i < underline_attributes.size(); ++i) {
-      const uint32 start = underline_attributes[i].start_index;
-      const uint32 end = underline_attributes[i].end_index;
+  const CompositionUnderlines text_underlines = text.underlines;
+  if (!text_underlines.empty()) {
+    for (size_t i = 0; i < text_underlines.size(); ++i) {
+      const uint32 start = text_underlines[i].start_offset;
+      const uint32 end = text_underlines[i].end_offset;
       if (start >= end)
         continue;
-      CompositionUnderline underline(char16_offsets[start],
-                                     char16_offsets[end],
-                                     SK_ColorBLACK,
-                                     false /* thick */,
-                                     SK_ColorTRANSPARENT);
-      if (underline_attributes[i].type ==
-          chromeos::CompositionText::COMPOSITION_TEXT_UNDERLINE_DOUBLE)
-        underline.thick = true;
-      else if (underline_attributes[i].type ==
-               chromeos::CompositionText::COMPOSITION_TEXT_UNDERLINE_ERROR)
-        underline.color = SK_ColorRED;
-      else if (underline_attributes[i].type ==
-               chromeos::CompositionText::COMPOSITION_TEXT_UNDERLINE_NONE)
-        underline.color = SK_ColorTRANSPARENT;
+      CompositionUnderline underline(
+          char16_offsets[start], char16_offsets[end], text_underlines[i].color,
+          text_underlines[i].thick, text_underlines[i].background_color);
       out_composition->underlines.push_back(underline);
     }
   }
 
-  DCHECK(text.selection_start() <= text.selection_end());
-  if (text.selection_start() < text.selection_end()) {
-    const uint32 start = text.selection_start();
-    const uint32 end = text.selection_end();
+  DCHECK(text.selection.start() <= text.selection.end());
+  if (text.selection.start() < text.selection.end()) {
+    const uint32 start = text.selection.start();
+    const uint32 end = text.selection.end();
     CompositionUnderline underline(char16_offsets[start],
                                    char16_offsets[end],
                                    SK_ColorBLACK,
diff --git a/ui/base/ime/input_method_chromeos.h b/ui/base/ime/input_method_chromeos.h
index fa845796..13cbdf9c 100644
--- a/ui/base/ime/input_method_chromeos.h
+++ b/ui/base/ime/input_method_chromeos.h
@@ -42,7 +42,7 @@
 
  protected:
   // Converts |text| into CompositionText.
-  void ExtractCompositionText(const chromeos::CompositionText& text,
+  void ExtractCompositionText(const CompositionText& text,
                               uint32 cursor_position,
                               CompositionText* out_composition) const;
 
@@ -99,7 +99,7 @@
 
   // ui::IMEInputContextHandlerInterface overrides:
   void CommitText(const std::string& text) override;
-  void UpdateCompositionText(const chromeos::CompositionText& text,
+  void UpdateCompositionText(const CompositionText& text,
                              uint32 cursor_pos,
                              bool visible) override;
   void DeleteSurroundingText(int32 offset, uint32 length) override;
diff --git a/ui/base/ime/input_method_chromeos_unittest.cc b/ui/base/ime/input_method_chromeos_unittest.cc
index b9af8c16d..b35a083 100644
--- a/ui/base/ime/input_method_chromeos_unittest.cc
+++ b/ui/base/ime/input_method_chromeos_unittest.cc
@@ -16,9 +16,9 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/ime/chromeos/composition_text_chromeos.h"
 #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h"
 #include "ui/base/ime/chromeos/mock_ime_engine_handler.h"
+#include "ui/base/ime/composition_text.h"
 #include "ui/base/ime/dummy_text_input_client.h"
 #include "ui/base/ime/ime_bridge.h"
 #include "ui/base/ime/ime_engine_handler_interface.h"
@@ -553,8 +553,8 @@
   const base::string16 kSampleAsciiText = UTF8ToUTF16("Sample Text");
   const uint32 kCursorPos = 2UL;
 
-  chromeos::CompositionText chromeos_composition_text;
-  chromeos_composition_text.set_text(kSampleAsciiText);
+  CompositionText chromeos_composition_text;
+  chromeos_composition_text.text = kSampleAsciiText;
 
   CompositionText composition_text;
   ime_->ExtractCompositionText(
@@ -575,121 +575,110 @@
   const uint32 kCursorPos = 2UL;
 
   // Set up chromeos composition text with one underline attribute.
-  chromeos::CompositionText chromeos_composition_text;
-  chromeos_composition_text.set_text(kSampleText);
-  chromeos::CompositionText::UnderlineAttribute underline;
-  underline.type = chromeos::CompositionText::COMPOSITION_TEXT_UNDERLINE_SINGLE;
-  underline.start_index = 1UL;
-  underline.end_index = 4UL;
-  chromeos_composition_text.mutable_underline_attributes()->push_back(
-      underline);
-
   CompositionText composition_text;
-  ime_->ExtractCompositionText(
-      chromeos_composition_text, kCursorPos, &composition_text);
-  EXPECT_EQ(kSampleText, composition_text.text);
+  composition_text.text = kSampleText;
+  CompositionUnderline underline(1UL, 4UL, SK_ColorBLACK, false,
+                                 SK_ColorTRANSPARENT);
+  composition_text.underlines.push_back(underline);
+
+  CompositionText composition_text2;
+  ime_->ExtractCompositionText(composition_text, kCursorPos,
+                               &composition_text2);
+  EXPECT_EQ(kSampleText, composition_text2.text);
   // If there is no selection, |selection| represents cursor position.
-  EXPECT_EQ(kCursorPos, composition_text.selection.start());
-  EXPECT_EQ(kCursorPos, composition_text.selection.end());
-  ASSERT_EQ(1UL, composition_text.underlines.size());
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_index),
-            composition_text.underlines[0].start_offset);
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_index),
-            composition_text.underlines[0].end_offset);
+  EXPECT_EQ(kCursorPos, composition_text2.selection.start());
+  EXPECT_EQ(kCursorPos, composition_text2.selection.end());
+  ASSERT_EQ(1UL, composition_text2.underlines.size());
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_offset),
+            composition_text2.underlines[0].start_offset);
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_offset),
+            composition_text2.underlines[0].end_offset);
   // Single underline represents as black thin line.
-  EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color);
-  EXPECT_FALSE(composition_text.underlines[0].thick);
+  EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
+  EXPECT_FALSE(composition_text2.underlines[0].thick);
   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
-            composition_text.underlines[0].background_color);
+            composition_text2.underlines[0].background_color);
 }
 
 TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_DoubleUnderline) {
   const uint32 kCursorPos = 2UL;
 
   // Set up chromeos composition text with one underline attribute.
-  chromeos::CompositionText chromeos_composition_text;
-  chromeos_composition_text.set_text(kSampleText);
-  chromeos::CompositionText::UnderlineAttribute underline;
-  underline.type = chromeos::CompositionText::COMPOSITION_TEXT_UNDERLINE_DOUBLE;
-  underline.start_index = 1UL;
-  underline.end_index = 4UL;
-  chromeos_composition_text.mutable_underline_attributes()->push_back(
-      underline);
-
   CompositionText composition_text;
-  ime_->ExtractCompositionText(
-      chromeos_composition_text, kCursorPos, &composition_text);
-  EXPECT_EQ(kSampleText, composition_text.text);
+  composition_text.text = kSampleText;
+  CompositionUnderline underline(1UL, 4UL, SK_ColorBLACK, true,
+                                 SK_ColorTRANSPARENT);
+  composition_text.underlines.push_back(underline);
+
+  CompositionText composition_text2;
+  ime_->ExtractCompositionText(composition_text, kCursorPos,
+                               &composition_text2);
+  EXPECT_EQ(kSampleText, composition_text2.text);
   // If there is no selection, |selection| represents cursor position.
-  EXPECT_EQ(kCursorPos, composition_text.selection.start());
-  EXPECT_EQ(kCursorPos, composition_text.selection.end());
-  ASSERT_EQ(1UL, composition_text.underlines.size());
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_index),
-            composition_text.underlines[0].start_offset);
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_index),
-            composition_text.underlines[0].end_offset);
+  EXPECT_EQ(kCursorPos, composition_text2.selection.start());
+  EXPECT_EQ(kCursorPos, composition_text2.selection.end());
+  ASSERT_EQ(1UL, composition_text2.underlines.size());
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_offset),
+            composition_text2.underlines[0].start_offset);
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_offset),
+            composition_text2.underlines[0].end_offset);
   // Double underline represents as black thick line.
-  EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color);
-  EXPECT_TRUE(composition_text.underlines[0].thick);
+  EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
+  EXPECT_TRUE(composition_text2.underlines[0].thick);
   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
-            composition_text.underlines[0].background_color);
+            composition_text2.underlines[0].background_color);
 }
 
 TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_ErrorUnderline) {
   const uint32 kCursorPos = 2UL;
 
   // Set up chromeos composition text with one underline attribute.
-  chromeos::CompositionText chromeos_composition_text;
-  chromeos_composition_text.set_text(kSampleText);
-  chromeos::CompositionText::UnderlineAttribute underline;
-  underline.type = chromeos::CompositionText::COMPOSITION_TEXT_UNDERLINE_ERROR;
-  underline.start_index = 1UL;
-  underline.end_index = 4UL;
-  chromeos_composition_text.mutable_underline_attributes()->push_back(
-      underline);
-
   CompositionText composition_text;
-  ime_->ExtractCompositionText(
-      chromeos_composition_text, kCursorPos, &composition_text);
-  EXPECT_EQ(kSampleText, composition_text.text);
-  EXPECT_EQ(kCursorPos, composition_text.selection.start());
-  EXPECT_EQ(kCursorPos, composition_text.selection.end());
-  ASSERT_EQ(1UL, composition_text.underlines.size());
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_index),
-            composition_text.underlines[0].start_offset);
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_index),
-            composition_text.underlines[0].end_offset);
+  composition_text.text = kSampleText;
+  CompositionUnderline underline(1UL, 4UL, SK_ColorRED, false,
+                                 SK_ColorTRANSPARENT);
+  composition_text.underlines.push_back(underline);
+
+  CompositionText composition_text2;
+  ime_->ExtractCompositionText(composition_text, kCursorPos,
+                               &composition_text2);
+  EXPECT_EQ(kSampleText, composition_text2.text);
+  EXPECT_EQ(kCursorPos, composition_text2.selection.start());
+  EXPECT_EQ(kCursorPos, composition_text2.selection.end());
+  ASSERT_EQ(1UL, composition_text2.underlines.size());
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_offset),
+            composition_text2.underlines[0].start_offset);
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_offset),
+            composition_text2.underlines[0].end_offset);
   // Error underline represents as red thin line.
-  EXPECT_EQ(SK_ColorRED, composition_text.underlines[0].color);
-  EXPECT_FALSE(composition_text.underlines[0].thick);
+  EXPECT_EQ(SK_ColorRED, composition_text2.underlines[0].color);
+  EXPECT_FALSE(composition_text2.underlines[0].thick);
 }
 
 TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_Selection) {
   const uint32 kCursorPos = 2UL;
 
   // Set up chromeos composition text with one underline attribute.
-  chromeos::CompositionText chromeos_composition_text;
-  chromeos_composition_text.set_text(kSampleText);
-  chromeos_composition_text.set_selection_start(1UL);
-  chromeos_composition_text.set_selection_end(4UL);
-
   CompositionText composition_text;
-  ime_->ExtractCompositionText(
-      chromeos_composition_text, kCursorPos, &composition_text);
-  EXPECT_EQ(kSampleText, composition_text.text);
-  EXPECT_EQ(kCursorPos, composition_text.selection.start());
-  EXPECT_EQ(kCursorPos, composition_text.selection.end());
-  ASSERT_EQ(1UL, composition_text.underlines.size());
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText,
-                             chromeos_composition_text.selection_start()),
-            composition_text.underlines[0].start_offset);
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText,
-                             chromeos_composition_text.selection_end()),
-            composition_text.underlines[0].end_offset);
-  EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color);
-  EXPECT_TRUE(composition_text.underlines[0].thick);
+  composition_text.text = kSampleText;
+  composition_text.selection.set_start(1UL);
+  composition_text.selection.set_end(4UL);
+
+  CompositionText composition_text2;
+  ime_->ExtractCompositionText(composition_text, kCursorPos,
+                               &composition_text2);
+  EXPECT_EQ(kSampleText, composition_text2.text);
+  EXPECT_EQ(kCursorPos, composition_text2.selection.start());
+  EXPECT_EQ(kCursorPos, composition_text2.selection.end());
+  ASSERT_EQ(1UL, composition_text2.underlines.size());
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.start()),
+            composition_text2.underlines[0].start_offset);
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.end()),
+            composition_text2.underlines[0].end_offset);
+  EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
+  EXPECT_TRUE(composition_text2.underlines[0].thick);
   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
-            composition_text.underlines[0].background_color);
+            composition_text2.underlines[0].background_color);
 }
 
 TEST_F(InputMethodChromeOSTest,
@@ -697,33 +686,30 @@
   const uint32 kCursorPos = 1UL;
 
   // Set up chromeos composition text with one underline attribute.
-  chromeos::CompositionText chromeos_composition_text;
-  chromeos_composition_text.set_text(kSampleText);
-  chromeos_composition_text.set_selection_start(kCursorPos);
-  chromeos_composition_text.set_selection_end(4UL);
-
   CompositionText composition_text;
-  ime_->ExtractCompositionText(
-      chromeos_composition_text, kCursorPos, &composition_text);
-  EXPECT_EQ(kSampleText, composition_text.text);
+  composition_text.text = kSampleText;
+  composition_text.selection.set_start(kCursorPos);
+  composition_text.selection.set_end(4UL);
+
+  CompositionText composition_text2;
+  ime_->ExtractCompositionText(composition_text, kCursorPos,
+                               &composition_text2);
+  EXPECT_EQ(kSampleText, composition_text2.text);
   // If the cursor position is same as selection bounds, selection start
   // position become opposit side of selection from cursor.
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText,
-                             chromeos_composition_text.selection_end()),
-            composition_text.selection.start());
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.end()),
+            composition_text2.selection.start());
   EXPECT_EQ(GetOffsetInUTF16(kSampleText, kCursorPos),
-            composition_text.selection.end());
-  ASSERT_EQ(1UL, composition_text.underlines.size());
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText,
-                             chromeos_composition_text.selection_start()),
-            composition_text.underlines[0].start_offset);
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText,
-                             chromeos_composition_text.selection_end()),
-            composition_text.underlines[0].end_offset);
-  EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color);
-  EXPECT_TRUE(composition_text.underlines[0].thick);
+            composition_text2.selection.end());
+  ASSERT_EQ(1UL, composition_text2.underlines.size());
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.start()),
+            composition_text2.underlines[0].start_offset);
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.end()),
+            composition_text2.underlines[0].end_offset);
+  EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
+  EXPECT_TRUE(composition_text2.underlines[0].thick);
   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
-            composition_text.underlines[0].background_color);
+            composition_text2.underlines[0].background_color);
 }
 
 TEST_F(InputMethodChromeOSTest,
@@ -731,33 +717,30 @@
   const uint32 kCursorPos = 4UL;
 
   // Set up chromeos composition text with one underline attribute.
-  chromeos::CompositionText chromeos_composition_text;
-  chromeos_composition_text.set_text(kSampleText);
-  chromeos_composition_text.set_selection_start(1UL);
-  chromeos_composition_text.set_selection_end(kCursorPos);
-
   CompositionText composition_text;
-  ime_->ExtractCompositionText(
-      chromeos_composition_text, kCursorPos, &composition_text);
-  EXPECT_EQ(kSampleText, composition_text.text);
+  composition_text.text = kSampleText;
+  composition_text.selection.set_start(1UL);
+  composition_text.selection.set_end(kCursorPos);
+
+  CompositionText composition_text2;
+  ime_->ExtractCompositionText(composition_text, kCursorPos,
+                               &composition_text2);
+  EXPECT_EQ(kSampleText, composition_text2.text);
   // If the cursor position is same as selection bounds, selection start
   // position become opposit side of selection from cursor.
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText,
-                             chromeos_composition_text.selection_start()),
-            composition_text.selection.start());
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.start()),
+            composition_text2.selection.start());
   EXPECT_EQ(GetOffsetInUTF16(kSampleText, kCursorPos),
-            composition_text.selection.end());
-  ASSERT_EQ(1UL, composition_text.underlines.size());
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText,
-                             chromeos_composition_text.selection_start()),
-            composition_text.underlines[0].start_offset);
-  EXPECT_EQ(GetOffsetInUTF16(kSampleText,
-                             chromeos_composition_text.selection_end()),
-            composition_text.underlines[0].end_offset);
-  EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color);
-  EXPECT_TRUE(composition_text.underlines[0].thick);
+            composition_text2.selection.end());
+  ASSERT_EQ(1UL, composition_text2.underlines.size());
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.start()),
+            composition_text2.underlines[0].start_offset);
+  EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.end()),
+            composition_text2.underlines[0].end_offset);
+  EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
+  EXPECT_TRUE(composition_text2.underlines[0].thick);
   EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
-            composition_text.underlines[0].background_color);
+            composition_text2.underlines[0].background_color);
 }
 
 TEST_F(InputMethodChromeOSTest, SurroundingText_NoSelectionTest) {
@@ -947,17 +930,17 @@
             mock_ime_engine_handler_->process_key_event_call_count());
   EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count());
 
-  chromeos::CompositionText comp;
-  comp.set_text(base::ASCIIToUTF16("B"));
+  CompositionText comp;
+  comp.text = base::ASCIIToUTF16("B");
   (static_cast<IMEInputContextHandlerInterface*>(ime_.get()))
-      ->UpdateCompositionText(comp, comp.text().length(), true);
+      ->UpdateCompositionText(comp, comp.text.length(), true);
 
   EXPECT_EQ(0, composition_text_.text[0]);
 
   // Do callback for first key event.
   first_callback.Run(true);
 
-  EXPECT_EQ(comp.text(), composition_text_.text);
+  EXPECT_EQ(comp.text, composition_text_.text);
 
   // Check the results for first key event.
   EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count());
diff --git a/ui/base/ime/ui_base_ime.gyp b/ui/base/ime/ui_base_ime.gyp
index 7e2a66c..22c3e72 100644
--- a/ui/base/ime/ui_base_ime.gyp
+++ b/ui/base/ime/ui_base_ime.gyp
@@ -36,8 +36,6 @@
         'chromeos/character_composer.h',
         'chromeos/component_extension_ime_manager.cc',
         'chromeos/component_extension_ime_manager.h',
-        'chromeos/composition_text_chromeos.cc',
-        'chromeos/composition_text_chromeos.h',
         'chromeos/extension_ime_util.cc',
         'chromeos/extension_ime_util.h',
         'chromeos/fake_ime_keyboard.cc',
@@ -75,7 +73,9 @@
         'composition_underline.h',
         'ime_bridge.cc',
         'ime_bridge.h',
+        'ime_engine_handler_interface.cc',
         'ime_engine_handler_interface.h',
+        'ime_engine_observer.h',
         'ime_input_context_handler_interface.h',
         'infolist_entry.cc',
         'infolist_entry.h',
diff --git a/ui/base/ui_base_tests.gyp b/ui/base/ui_base_tests.gyp
index 5018384..2c2ec55 100644
--- a/ui/base/ui_base_tests.gyp
+++ b/ui/base/ui_base_tests.gyp
@@ -71,8 +71,8 @@
         'cocoa/tracking_area_unittest.mm',
         'dragdrop/os_exchange_data_provider_aurax11_unittest.cc',
         'ime/candidate_window_unittest.cc',
+        'ime/composition_text_unittest.cc',
         'ime/chromeos/character_composer_unittest.cc',
-        'ime/chromeos/composition_text_chromeos_unittest.cc',
         'ime/composition_text_util_pango_unittest.cc',
         'ime/input_method_base_unittest.cc',
         'ime/input_method_chromeos_unittest.cc',
diff --git a/ui/chromeos/translations/ui_chromeos_strings_hu.xtb b/ui/chromeos/translations/ui_chromeos_strings_hu.xtb
index 5b8cdf62..208e93b3 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_hu.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_hu.xtb
@@ -4,7 +4,7 @@
 <translation id="1119447706177454957">Belső hiba</translation>
 <translation id="153454903766751181">Mobilmodem inicializálása...</translation>
 <translation id="158849752021629804">Otthoni hálózat szükséges</translation>
-<translation id="1661867754829461514">Hiányzó PIN kód</translation>
+<translation id="1661867754829461514">Hiányzó PIN-kód</translation>
 <translation id="1773212559869067373">A hitelesítési tanúsítvány helyileg elutasítva</translation>
 <translation id="1829129547161959350">Pingvin</translation>
 <translation id="1850504506766569011">Wi-Fi kikapcsolva.</translation>
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn
index 29b64c5..80097cd 100644
--- a/ui/events/BUILD.gn
+++ b/ui/events/BUILD.gn
@@ -5,6 +5,10 @@
 import("//build/config/ui.gni")
 import("//testing/test.gni")
 
+if (is_android) {
+  import("//build/config/android/rules.gni")
+}
+
 static_library("dom_keycode_converter") {
   sources = [
     "keycodes/dom/dom_code.h",
@@ -181,6 +185,16 @@
   if (is_win || is_mac || use_x11 || use_ozone || (is_android && use_aura)) {
     sources -= [ "events_stub.cc" ]
   }
+
+  if (is_android) {
+    sources += [
+      "android/events_jni_registrar.cc",
+      "android/events_jni_registrar.h",
+      "android/motion_event_android.cc",
+      "android/motion_event_android.h",
+    ]
+    deps += [ ":motionevent_jni_headers" ]
+  }
 }
 
 component("gesture_detection") {
@@ -413,4 +427,15 @@
       "gestures/motion_event_aura_unittest.cc",
     ]
   }
+
+  if (is_android) {
+    sources += [ "android/motion_event_android_unittest.cc" ]
+  }
+}
+
+if (is_android) {
+  generate_jar_jni("motionevent_jni_headers") {
+    jni_package = "ui"
+    classes = [ "android/view/MotionEvent.class" ]
+  }
 }
diff --git a/ui/events/android/DEPS b/ui/events/android/DEPS
new file mode 100644
index 0000000..c80012b5
--- /dev/null
+++ b/ui/events/android/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+jni",
+]
diff --git a/ui/events/android/OWNERS b/ui/events/android/OWNERS
new file mode 100644
index 0000000..2328e39d
--- /dev/null
+++ b/ui/events/android/OWNERS
@@ -0,0 +1,2 @@
+aelias@chromium.org
+tdresser@chromium.org
\ No newline at end of file
diff --git a/ui/events/android/events_jni_registrar.cc b/ui/events/android/events_jni_registrar.cc
new file mode 100644
index 0000000..635a4ab
--- /dev/null
+++ b/ui/events/android/events_jni_registrar.cc
@@ -0,0 +1,26 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/android/events_jni_registrar.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_registrar.h"
+#include "ui/events/android/motion_event_android.h"
+
+namespace ui {
+namespace events {
+namespace android {
+
+static base::android::RegistrationMethod kAndroidRegisteredMethods[] = {
+    {"MotionEventAndroid", ui::MotionEventAndroid::RegisterMotionEventAndroid},
+};
+
+bool RegisterJni(JNIEnv* env) {
+  return RegisterNativeMethods(env, kAndroidRegisteredMethods,
+                               arraysize(kAndroidRegisteredMethods));
+}
+
+}  // namespace android
+}  // namespace events
+}  // namespace ui
diff --git a/ui/events/android/events_jni_registrar.h b/ui/events/android/events_jni_registrar.h
new file mode 100644
index 0000000..4b2b027
--- /dev/null
+++ b/ui/events/android/events_jni_registrar.h
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_ANDROID_EVENTS_JNI_REGISTRAR_H_
+#define UI_EVENTS_ANDROID_EVENTS_JNI_REGISTRAR_H_
+
+#include <jni.h>
+
+#include "ui/events/events_export.h"
+
+namespace ui {
+namespace events {
+namespace android {
+
+// Register all JNI bindings necessary for chrome.
+EVENTS_EXPORT bool RegisterJni(JNIEnv* env);
+
+}  // namespace android
+}  // namespace events
+}  // namespace ui
+
+
+
+#endif  // UI_EVENTS_ANDROID_EVENTS_JNI_REGISTRAR_H_
diff --git a/content/browser/renderer_host/input/motion_event_android.cc b/ui/events/android/motion_event_android.cc
similarity index 98%
rename from content/browser/renderer_host/input/motion_event_android.cc
rename to ui/events/android/motion_event_android.cc
index 6392e90..324c3e75 100644
--- a/content/browser/renderer_host/input/motion_event_android.cc
+++ b/ui/events/android/motion_event_android.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/renderer_host/input/motion_event_android.h"
+#include "ui/events/android/motion_event_android.h"
 
 #include <android/input.h>
 
@@ -16,7 +16,7 @@
 using base::android::AttachCurrentThread;
 using namespace JNI_MotionEvent;
 
-namespace content {
+namespace ui {
 namespace {
 
 MotionEventAndroid::Action FromAndroidAction(int android_action) {
diff --git a/content/browser/renderer_host/input/motion_event_android.h b/ui/events/android/motion_event_android.h
similarity index 92%
rename from content/browser/renderer_host/input/motion_event_android.h
rename to ui/events/android/motion_event_android.h
index d581ce0..db79a141 100644
--- a/content/browser/renderer_host/input/motion_event_android.h
+++ b/ui/events/android/motion_event_android.h
@@ -3,24 +3,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_ANDROID_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_ANDROID_H_
+#ifndef UI_EVENTS_ANDROID_MOTION_EVENT_ANDROID_H_
+#define UI_EVENTS_ANDROID_MOTION_EVENT_ANDROID_H_
 
 #include <jni.h>
 
 #include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
-#include "content/common/content_export.h"
+#include "ui/events/events_export.h"
 #include "ui/events/gesture_detection/motion_event.h"
 #include "ui/gfx/geometry/point_f.h"
 
-namespace content {
+namespace ui {
 
 // Implementation of ui::MotionEvent wrapping a native Android MotionEvent.
 // All *input* coordinates are in device pixels (as with Android MotionEvent),
 // while all *output* coordinates are in DIPs (as with WebTouchEvent).
-class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
+class EVENTS_EXPORT MotionEventAndroid : public MotionEvent {
  public:
   struct Pointer {
     Pointer(jint id,
@@ -135,4 +136,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_BROWSER_RENDERER_HOST_INPUT_MOTION_EVENT_ANDROID_H_
+#endif  // UI_EVENTS_ANDROID_MOTION_EVENT_ANDROID_H_
diff --git a/content/browser/renderer_host/input/motion_event_android_unittest.cc b/ui/events/android/motion_event_android_unittest.cc
similarity index 98%
rename from content/browser/renderer_host/input/motion_event_android_unittest.cc
rename to ui/events/android/motion_event_android_unittest.cc
index c888aca..26d82e36 100644
--- a/content/browser/renderer_host/input/motion_event_android_unittest.cc
+++ b/ui/events/android/motion_event_android_unittest.cc
@@ -5,14 +5,14 @@
 #include <android/input.h>
 
 #include "base/android/jni_android.h"
-#include "content/browser/renderer_host/input/motion_event_android.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/android/motion_event_android.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/test/motion_event_test_utils.h"
 
-using ui::MotionEvent;
+namespace ui {
+class MotionEvent;
 
-namespace content {
 namespace {
 const float kPixToDip = 0.5f;
 
diff --git a/ui/events/events.gyp b/ui/events/events.gyp
index c9e3edc..8a15401 100644
--- a/ui/events/events.gyp
+++ b/ui/events/events.gyp
@@ -197,6 +197,17 @@
             'ozone/events_ozone.gyp:events_ozone_layout',
           ],
         }],
+        ['OS=="android"', {
+          'sources': [
+            'android/events_jni_registrar.cc',
+            'android/events_jni_registrar.h',
+            'android/motion_event_android.cc',
+            'android/motion_event_android.h',
+          ],
+          'dependencies': [
+            'motionevent_jni_headers',
+          ],
+        }],
       ],
     },
     {
@@ -479,6 +490,9 @@
           ],
         }],
         ['OS == "android"', {
+          'sources': [
+            'android/motion_event_android_unittest.cc',
+          ],
           'dependencies': [
             '../../testing/android/native_test.gyp:native_test_native_code',
           ],
@@ -490,6 +504,15 @@
     ['OS == "android"', {
       'targets': [
         {
+          'target_name': 'motionevent_jni_headers',
+          'type': 'none',
+          'variables': {
+            'jni_gen_package': 'ui',
+            'input_java_class': 'android/view/MotionEvent.class',
+          },
+          'includes': [ '../../build/jar_file_jni_generator.gypi' ],
+        },
+        {
           'target_name': 'events_unittests_apk',
           'type': 'none',
           'dependencies': [
diff --git a/ui/events/ozone/device/device_manager_manual.cc b/ui/events/ozone/device/device_manager_manual.cc
index f5e1eca..65d1c253 100644
--- a/ui/events/ozone/device/device_manager_manual.cc
+++ b/ui/events/ozone/device/device_manager_manual.cc
@@ -17,10 +17,9 @@
 namespace {
 
 void ScanDevicesOnWorkerThread(std::vector<base::FilePath>* result) {
-  base::FileEnumerator file_enum(base::FilePath("/dev/input"),
-                                 false,
-                                 base::FileEnumerator::FILES,
-                                 "event*[0-9]");
+  base::FileEnumerator file_enum(
+      base::FilePath(FILE_PATH_LITERAL("/dev/input")), false,
+      base::FileEnumerator::FILES, FILE_PATH_LITERAL("event*[0-9]"));
   for (base::FilePath path = file_enum.Next(); !path.empty();
        path = file_enum.Next()) {
     result->push_back(path);
diff --git a/ui/file_manager/file_manager_resources.grd b/ui/file_manager/file_manager_resources.grd
index ba8cc28025..a0aa1e6 100644
--- a/ui/file_manager/file_manager_resources.grd
+++ b/ui/file_manager/file_manager_resources.grd
@@ -192,18 +192,7 @@
 
       <!-- Custom cursors (which grit cannot inline). -->
       <include name="IDR_FILE_MANAGER_IMG_GALLERY_CURSOR_CROP" file="gallery/images/100/cursor_crop.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_CURSOR_LEFTRIGHT" file="gallery/images/100/cursor_leftright.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_CURSOR_MOVE" file="gallery/images/100/cursor_move.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_CURSOR_NWSE" file="gallery/images/100/cursor_nwse.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_CURSOR_SWNE" file="gallery/images/100/cursor_swne.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_CURSOR_UPDOWN" file="gallery/images/100/cursor_updown.png" type="BINDATA" />
-
       <include name="IDR_FILE_MANAGER_IMG_GALLERY_2X_CURSOR_CROP" file="gallery/images/200/cursor_crop.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_2X_CURSOR_LEFTRIGHT" file="gallery/images/200/cursor_leftright.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_2X_CURSOR_MOVE" file="gallery/images/200/cursor_move.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_2X_CURSOR_NWSE" file="gallery/images/200/cursor_nwse.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_2X_CURSOR_SWNE" file="gallery/images/200/cursor_swne.png" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_IMG_GALLERY_2X_CURSOR_UPDOWN" file="gallery/images/200/cursor_updown.png" type="BINDATA" />
 
       <!-- Image loader extension manifest and scripts. -->
       <if expr="image_loader_extension">
diff --git a/ui/file_manager/gallery/css/gallery.css b/ui/file_manager/gallery/css/gallery.css
index 08b532e..523142b 100644
--- a/ui/file_manager/gallery/css/gallery.css
+++ b/ui/file_manager/gallery/css/gallery.css
@@ -83,9 +83,7 @@
 }
 
 .gallery[tools] .image-container[cursor='move'] {
-  cursor: -webkit-image-set(
-      url(../images/100/cursor_move.png) 1x,
-      url(../images/200/cursor_move.png) 2x) 15 15, auto;
+  cursor: move;
 }
 
 .gallery[tools] .image-container[cursor='crop'] {
@@ -94,32 +92,33 @@
       url(../images/200/cursor_crop.png) 2x) 15 15, auto;
 }
 
+/**
+ * If large cursor or high contrast is enabled, falls back to default cursor
+ * since they don't support css custom cursor.
+ */
+.gallery[tools][large-cursor] .image-container[cursor='crop'],
+.gallery[tools][high-contrast] .image-container[cursor='crop'] {
+  cursor: default;
+}
+
 .gallery[tools] .image-container[cursor='n-resize'],
 .gallery[tools] .image-container[cursor='s-resize'] {
-  cursor: -webkit-image-set(
-      url(../images/100/cursor_updown.png) 1x,
-      url(../images/200/cursor_updown.png) 2x) 15 15, auto;
+  cursor: ns-resize;
 }
 
 .gallery[tools] .image-container[cursor='e-resize'],
 .gallery[tools] .image-container[cursor='w-resize'] {
-  cursor: -webkit-image-set(
-      url(../images/100/cursor_leftright.png) 1x,
-      url(../images/200/cursor_leftright.png) 2x) 15 15, auto;
+  cursor: ew-resize;
 }
 
 .gallery[tools] .image-container[cursor='nw-resize'],
 .gallery[tools] .image-container[cursor='se-resize'] {
-  cursor: -webkit-image-set(
-      url(../images/100/cursor_nwse.png) 1x,
-      url(../images/200/cursor_nwse.png) 2x) 15 15, auto;
+  cursor: nwse-resize;
 }
 
 .gallery[tools] .image-container[cursor='ne-resize'],
 .gallery[tools] .image-container[cursor='sw-resize'] {
-  cursor: -webkit-image-set(
-      url(../images/100/cursor_swne.png) 1x,
-      url(../images/200/cursor_swne.png) 2x) 15 15, auto;
+  cursor: nesw-resize;
 }
 
 .gallery .image-container > .image {
diff --git a/ui/file_manager/gallery/images/100/cursor_leftright.png b/ui/file_manager/gallery/images/100/cursor_leftright.png
deleted file mode 100644
index 30eeb03a..0000000
--- a/ui/file_manager/gallery/images/100/cursor_leftright.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/100/cursor_move.png b/ui/file_manager/gallery/images/100/cursor_move.png
deleted file mode 100644
index c5026d1..0000000
--- a/ui/file_manager/gallery/images/100/cursor_move.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/100/cursor_nwse.png b/ui/file_manager/gallery/images/100/cursor_nwse.png
deleted file mode 100644
index 87fb564..0000000
--- a/ui/file_manager/gallery/images/100/cursor_nwse.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/100/cursor_swne.png b/ui/file_manager/gallery/images/100/cursor_swne.png
deleted file mode 100644
index 5e34475..0000000
--- a/ui/file_manager/gallery/images/100/cursor_swne.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/100/cursor_updown.png b/ui/file_manager/gallery/images/100/cursor_updown.png
deleted file mode 100644
index f3a42247..0000000
--- a/ui/file_manager/gallery/images/100/cursor_updown.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/200/cursor_leftright.png b/ui/file_manager/gallery/images/200/cursor_leftright.png
deleted file mode 100644
index a7ee09c..0000000
--- a/ui/file_manager/gallery/images/200/cursor_leftright.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/200/cursor_move.png b/ui/file_manager/gallery/images/200/cursor_move.png
deleted file mode 100644
index faa3c8a..0000000
--- a/ui/file_manager/gallery/images/200/cursor_move.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/200/cursor_nwse.png b/ui/file_manager/gallery/images/200/cursor_nwse.png
deleted file mode 100644
index 0cd6399..0000000
--- a/ui/file_manager/gallery/images/200/cursor_nwse.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/200/cursor_swne.png b/ui/file_manager/gallery/images/200/cursor_swne.png
deleted file mode 100644
index 04d9dc0..0000000
--- a/ui/file_manager/gallery/images/200/cursor_swne.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/images/200/cursor_updown.png b/ui/file_manager/gallery/images/200/cursor_updown.png
deleted file mode 100644
index 1e9adfb..0000000
--- a/ui/file_manager/gallery/images/200/cursor_updown.png
+++ /dev/null
Binary files differ
diff --git a/ui/file_manager/gallery/js/gallery.js b/ui/file_manager/gallery/js/gallery.js
index 6d0d775..499130a 100644
--- a/ui/file_manager/gallery/js/gallery.js
+++ b/ui/file_manager/gallery/js/gallery.js
@@ -211,6 +211,20 @@
    * @const
    */
   this.onSubModeChangedBound_ = this.onSubModeChanged_.bind(this);
+
+  chrome.accessibilityFeatures.largeCursor.onChange.addListener(
+      this.onGetOrChangedAccessibilityConfiguration_.bind(
+          this, 'large-cursor'));
+  chrome.accessibilityFeatures.largeCursor.get({},
+      this.onGetOrChangedAccessibilityConfiguration_.bind(
+          this, 'large-cursor'));
+
+  chrome.accessibilityFeatures.highContrast.onChange.addListener(
+      this.onGetOrChangedAccessibilityConfiguration_.bind(
+          this, 'high-contrast'));
+  chrome.accessibilityFeatures.highContrast.get({},
+      this.onGetOrChangedAccessibilityConfiguration_.bind(
+          this, 'high-contrast'));
 }
 
 /**
@@ -264,6 +278,22 @@
 };
 
 /**
+ * Updates attributes of container element when accessibility configuration has
+ * been changed.
+ * @param {string} name
+ * @param {Object} details
+ * @private
+ */
+Gallery.prototype.onGetOrChangedAccessibilityConfiguration_ = function(
+    name, details) {
+  if (details.value) {
+    this.container_.setAttribute(name, true);
+  } else {
+    this.container_.removeAttribute(name);
+  }
+};
+
+/**
  * Closes gallery when a volume containing the selected item is unmounted.
  * @param {!Event} event The unmount event.
  * @private
@@ -561,8 +591,6 @@
           }.bind(this));
       this.bottomToolbar_.hidden = true;
     } else {
-      // TODO(yawano): Make animation smooth. With this implementation,
-      //     animation starts after the image is fully loaded.
       this.setCurrentMode_(this.slideMode_);
       this.slideMode_.enter(
           thumbnailRect,
diff --git a/ui/file_manager/gallery/js/image_editor/image_view.js b/ui/file_manager/gallery/js/image_editor/image_view.js
index 6e3206b..5e8bffc 100644
--- a/ui/file_manager/gallery/js/image_editor/image_view.js
+++ b/ui/file_manager/gallery/js/image_editor/image_view.js
@@ -151,13 +151,15 @@
   if (item.screenImage)
     return ImageView.LoadTarget.CACHED_THUMBNAIL;
 
-  // Only show thumbnails if there is no effect or the effect is Slide.
+  // Only show thumbnails if there is no effect or the effect is Slide or
+  // ZoomToScreen.
   var thumbnailLoader = new ThumbnailLoader(
       item.getEntry(),
       ThumbnailLoader.LoaderType.CANVAS,
       item.getThumbnailMetadataItem());
   if ((effect instanceof ImageView.Effect.None ||
-       effect instanceof ImageView.Effect.Slide) &&
+       effect instanceof ImageView.Effect.Slide ||
+       effect instanceof ImageView.Effect.ZoomToScreen) &&
       thumbnailLoader.getLoadTarget() !==
       ThumbnailLoader.LoadTarget.FILE_ENTRY) {
     return ImageView.LoadTarget.THUMBNAIL;
diff --git a/ui/file_manager/gallery/js/image_editor/image_view_unittest.html b/ui/file_manager/gallery/js/image_editor/image_view_unittest.html
index 88248e2..e72124f 100644
--- a/ui/file_manager/gallery/js/image_editor/image_view_unittest.html
+++ b/ui/file_manager/gallery/js/image_editor/image_view_unittest.html
@@ -11,6 +11,7 @@
 <script src="../../../file_manager/foreground/js/thumbnail_loader.js"></script>
 <script src="../gallery_item.js"></script>
 <script src="image_buffer.js"></script>
+<script src="image_util.js"></script>
 <script src="image_view.js"></script>
 <script src="image_view_unittest.js"></script>
 
diff --git a/ui/file_manager/gallery/js/image_editor/image_view_unittest.js b/ui/file_manager/gallery/js/image_editor/image_view_unittest.js
index 4dc39d9..80a9b8bc 100644
--- a/ui/file_manager/gallery/js/image_editor/image_view_unittest.js
+++ b/ui/file_manager/gallery/js/image_editor/image_view_unittest.js
@@ -54,6 +54,15 @@
       ImageView.getLoadTarget(
           itemWithExternalThumbnailSlide, new ImageView.Effect.Slide(1)));
 
+  // Item with external thumbnail shown by zoom to screen effect.
+  var itemWithExternalThumbnailZoomToScreen = new GalleryItem(
+      mockEntry, null, {external: {thumbnailUrl: 'url'}}, null, false);
+  assertEquals(
+      ImageView.LoadTarget.THUMBNAIL,
+      ImageView.getLoadTarget(
+          itemWithExternalThumbnailZoomToScreen,
+          new ImageView.Effect.ZoomToScreen(new ImageRect(0, 0, 100, 100))));
+
   // Item with external thumbnail shown by zoom effect.
   var itemWithExternalThumbnailZoom = new GalleryItem(
       mockEntry, null, {external: {thumbnailUrl: 'url'}}, null, false);
diff --git a/ui/gfx/blit.cc b/ui/gfx/blit.cc
index 81984c8..61a7d90 100644
--- a/ui/gfx/blit.cc
+++ b/ui/gfx/blit.cc
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "build/build_config.h"
 #include "skia/ext/platform_canvas.h"
+#include "third_party/skia/include/core/SkPixmap.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/vector2d.h"
@@ -143,13 +144,12 @@
   // Cairo has no nice scroll function so we do our own. On Mac it's possible to
   // use platform scroll code, but it's complex so we just use the same path
   // here. Either way it will be software-only, so it shouldn't matter much.
-  SkBitmap& bitmap = const_cast<SkBitmap&>(
-      skia::GetTopDevice(*canvas)->accessBitmap(true));
-  SkAutoLockPixels lock(bitmap);
+  SkPixmap pixmap;
+  skia::GetWritablePixels(canvas, &pixmap);
 
   // We expect all coords to be inside the canvas, so clip here.
   gfx::Rect clip = gfx::IntersectRects(
-      in_clip, gfx::Rect(0, 0, bitmap.width(), bitmap.height()));
+      in_clip, gfx::Rect(0, 0, pixmap.width(), pixmap.height()));
 
   // Compute the set of pixels we'll actually end up painting.
   gfx::Rect dest_rect = gfx::IntersectRects(clip + offset, clip);
@@ -163,15 +163,15 @@
   if (offset.y() > 0) {
     // Data is moving down, copy from the bottom up.
     for (int y = dest_rect.height() - 1; y >= 0; y--) {
-      memcpy(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y),
-             bitmap.getAddr32(src_rect.x(), src_rect.y() + y),
+      memcpy(pixmap.writable_addr32(dest_rect.x(), dest_rect.y() + y),
+             pixmap.addr32(src_rect.x(), src_rect.y() + y),
              row_bytes);
     }
   } else if (offset.y() < 0) {
     // Data is moving up, copy from the top down.
     for (int y = 0; y < dest_rect.height(); y++) {
-      memcpy(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y),
-             bitmap.getAddr32(src_rect.x(), src_rect.y() + y),
+      memcpy(pixmap.writable_addr32(dest_rect.x(), dest_rect.y() + y),
+             pixmap.addr32(src_rect.x(), src_rect.y() + y),
              row_bytes);
     }
   } else if (offset.x() != 0) {
@@ -179,8 +179,8 @@
     // to-top, but have to be careful about the order for copying each row.
     // Fortunately, memmove already handles this for us.
     for (int y = 0; y < dest_rect.height(); y++) {
-      memmove(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y),
-              bitmap.getAddr32(src_rect.x(), src_rect.y() + y),
+      memmove(pixmap.writable_addr32(dest_rect.x(), dest_rect.y() + y),
+              pixmap.addr32(src_rect.x(), src_rect.y() + y),
               row_bytes);
     }
   }
diff --git a/ui/gfx/canvas_skia.cc b/ui/gfx/canvas_skia.cc
index 0d1b70d0..88744c9 100644
--- a/ui/gfx/canvas_skia.cc
+++ b/ui/gfx/canvas_skia.cc
@@ -8,6 +8,8 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/numerics/safe_conversions.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkPixmap.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/geometry/rect.h"
@@ -27,24 +29,24 @@
 // pixel against both the halo color and transparent since
 // |DrawStringRectWithHalo| will modify the bitmap as it goes, and cleared
 // pixels shouldn't count as changed.
-bool PixelShouldGetHalo(const SkBitmap& bitmap,
+bool PixelShouldGetHalo(const SkPixmap& pixmap,
                         int x, int y,
                         SkColor halo_color) {
   if (x > 0 &&
-      *bitmap.getAddr32(x - 1, y) != halo_color &&
-      *bitmap.getAddr32(x - 1, y) != 0)
+      *pixmap.addr32(x - 1, y) != halo_color &&
+      *pixmap.addr32(x - 1, y) != 0)
     return true;  // Touched pixel to the left.
-  if (x < bitmap.width() - 1 &&
-      *bitmap.getAddr32(x + 1, y) != halo_color &&
-      *bitmap.getAddr32(x + 1, y) != 0)
+  if (x < pixmap.width() - 1 &&
+      *pixmap.addr32(x + 1, y) != halo_color &&
+      *pixmap.addr32(x + 1, y) != 0)
     return true;  // Touched pixel to the right.
   if (y > 0 &&
-      *bitmap.getAddr32(x, y - 1) != halo_color &&
-      *bitmap.getAddr32(x, y - 1) != 0)
+      *pixmap.addr32(x, y - 1) != halo_color &&
+      *pixmap.addr32(x, y - 1) != 0)
     return true;  // Touched pixel above.
-  if (y < bitmap.height() - 1 &&
-      *bitmap.getAddr32(x, y + 1) != halo_color &&
-      *bitmap.getAddr32(x, y + 1) != 0)
+  if (y < pixmap.height() - 1 &&
+      *pixmap.addr32(x, y + 1) != halo_color &&
+      *pixmap.addr32(x, y + 1) != 0)
     return true;  // Touched pixel below.
   return false;
 }
@@ -291,16 +293,16 @@
       Rect(1, 1, display_rect.width(), display_rect.height()), flags);
 
   uint32_t halo_premul = SkPreMultiplyColor(halo_color);
-  SkBitmap& text_bitmap = const_cast<SkBitmap&>(
-      skia::GetTopDevice(*text_canvas.sk_canvas())->accessBitmap(true));
+  SkPixmap pixmap;
+  skia::GetWritablePixels(text_canvas.sk_canvas(), &pixmap);
 
-  for (int cur_y = 0; cur_y < text_bitmap.height(); cur_y++) {
-    uint32_t* text_row = text_bitmap.getAddr32(0, cur_y);
-    for (int cur_x = 0; cur_x < text_bitmap.width(); cur_x++) {
+  for (int cur_y = 0; cur_y < pixmap.height(); cur_y++) {
+    uint32_t* text_row = pixmap.writable_addr32(0, cur_y);
+    for (int cur_x = 0; cur_x < pixmap.width(); cur_x++) {
       if (text_row[cur_x] == halo_premul) {
         // This pixel was not touched by the text routines. See if it borders
         // a touched pixel in any of the 4 directions (not diagonally).
-        if (!PixelShouldGetHalo(text_bitmap, cur_x, cur_y, halo_premul))
+        if (!PixelShouldGetHalo(pixmap, cur_x, cur_y, halo_premul))
           text_row[cur_x] = 0;  // Make transparent.
       } else {
         text_row[cur_x] |= 0xff << SK_A32_SHIFT;  // Make opaque.
@@ -309,7 +311,10 @@
   }
 
   // Draw the halo bitmap with blur.
-  ImageSkia text_image = ImageSkia(ImageSkiaRep(text_bitmap,
+  SkBitmap bitmap;
+  bitmap.installPixels(pixmap.info(), pixmap.writable_addr(),
+                       pixmap.rowBytes());
+  ImageSkia text_image = ImageSkia(ImageSkiaRep(bitmap,
       text_canvas.image_scale()));
   DrawImageInt(text_image, display_rect.x() - 1, display_rect.y() - 1);
 }
diff --git a/ui/gl/gl_fence.cc b/ui/gl/gl_fence.cc
index 0fb3a74..694f22d 100644
--- a/ui/gl/gl_fence.cc
+++ b/ui/gl/gl_fence.cc
@@ -11,6 +11,7 @@
 #include "ui/gl/gl_fence_egl.h"
 #include "ui/gl/gl_fence_nv.h"
 #include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_version_info.h"
 
 #if defined(OS_MACOSX)
@@ -28,6 +29,7 @@
 bool GLFence::IsSupported() {
   DCHECK(GetGLVersionInfo());
   return g_driver_gl.ext.b_GL_ARB_sync || GetGLVersionInfo()->is_es3 ||
+         GetGLImplementation() == kGLImplementationDesktopGLCoreProfile ||
 #if defined(OS_MACOSX)
          g_driver_gl.ext.b_GL_APPLE_fence ||
 #else
@@ -43,7 +45,8 @@
   scoped_ptr<GLFence> fence;
   // Prefer ARB_sync which supports server-side wait.
   if (g_driver_gl.ext.b_GL_ARB_sync ||
-      GetGLVersionInfo()->is_es3) {
+      GetGLVersionInfo()->is_es3 ||
+      GetGLImplementation() == kGLImplementationDesktopGLCoreProfile) {
     fence.reset(new GLFenceARB);
 #if defined(OS_MACOSX)
   } else if (g_driver_gl.ext.b_GL_APPLE_fence) {
diff --git a/ui/gl/gl_image_io_surface.mm b/ui/gl/gl_image_io_surface.mm
index d6ac250..dfd8df9 100644
--- a/ui/gl/gl_image_io_surface.mm
+++ b/ui/gl/gl_image_io_surface.mm
@@ -28,7 +28,7 @@
 
 bool ValidInternalFormat(unsigned internalformat) {
   switch (internalformat) {
-    case GL_R8:
+    case GL_RED:
     case GL_BGRA_EXT:
     case GL_RGB:
     case GL_RGB_YCBCR_422_CHROMIUM:
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc
index 2f8a45d..03391ba 100644
--- a/ui/gl/gl_image_memory.cc
+++ b/ui/gl/gl_image_memory.cc
@@ -23,7 +23,7 @@
     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
     case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
     case GL_ETC1_RGB8_OES:
-    case GL_R8:
+    case GL_RED:
     case GL_RGB:
     case GL_RGBA:
     case GL_BGRA_EXT:
diff --git a/ui/strings/translations/ui_strings_ca.xtb b/ui/strings/translations/ui_strings_ca.xtb
index bc324a16..2ba519f 100644
--- a/ui/strings/translations/ui_strings_ca.xtb
+++ b/ui/strings/translations/ui_strings_ca.xtb
@@ -145,5 +145,5 @@
 <translation id="9170848237812810038">&amp;Desfés</translation>
 <translation id="928465423150706909">Mou al final de la línia</translation>
 <translation id="932327136139879170">Pàgina d'inici</translation>
-<translation id="945522503751344254">Envia comentaris</translation>
+<translation id="945522503751344254">Envia suggeriments</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ui/surface/transport_dib.h b/ui/surface/transport_dib.h
index a166238..3016548 100644
--- a/ui/surface/transport_dib.h
+++ b/ui/surface/transport_dib.h
@@ -58,7 +58,8 @@
 
   // Returns a canvas using the memory of this TransportDIB. The returned
   // pointer will be owned by the caller. The bitmap will be of the given size,
-  // which should fit inside this memory.
+  // which should fit inside this memory. Bitmaps returned will be either
+  // opaque or have premultiplied alpha.
   //
   // On POSIX, this |TransportDIB| will be mapped if not already. On Windows,
   // this |TransportDIB| will NOT be mapped and should not be mapped prior,
@@ -66,7 +67,7 @@
   //
   // Will return NULL on allocation failure. This could be because the image
   // is too large to map into the current process' address space.
-  SkCanvas* GetPlatformCanvas(int w, int h);
+  SkCanvas* GetPlatformCanvas(int w, int h, bool opaque);
 
   // Map the DIB into the current process if it is not already. This is used to
   // map a DIB that has already been created. Returns true if the DIB is mapped.
diff --git a/ui/surface/transport_dib_posix.cc b/ui/surface/transport_dib_posix.cc
index 25b2529..f52fcbc 100644
--- a/ui/surface/transport_dib_posix.cc
+++ b/ui/surface/transport_dib_posix.cc
@@ -54,10 +54,11 @@
   return base::SharedMemory::IsHandleValid(dib);
 }
 
-skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) {
+skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h,
+                                                      bool opaque) {
   if ((!memory() && !Map()) || !VerifyCanvasSize(w, h))
     return NULL;
-  return skia::CreatePlatformCanvas(w, h, true,
+  return skia::CreatePlatformCanvas(w, h, opaque,
                                     reinterpret_cast<uint8_t*>(memory()),
                                     skia::RETURN_NULL_ON_FAILURE);
 }
diff --git a/ui/surface/transport_dib_win.cc b/ui/surface/transport_dib_win.cc
index af55af2..2d5d5d125 100644
--- a/ui/surface/transport_dib_win.cc
+++ b/ui/surface/transport_dib_win.cc
@@ -56,7 +56,8 @@
   return dib.IsValid();
 }
 
-skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) {
+skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h,
+                                                      bool opaque) {
   // This DIB already mapped the file into this process, but PlatformCanvas
   // will map it again.
   DCHECK(!memory()) << "Mapped file twice in the same process.";
@@ -65,7 +66,7 @@
   // Windows will fail to map the section if the dimensions of the canvas
   // are too large.
   skia::PlatformCanvas* canvas = skia::CreatePlatformCanvas(
-      w, h, true, shared_memory_.handle().GetHandle(),
+      w, h, opaque, shared_memory_.handle().GetHandle(),
       skia::RETURN_NULL_ON_FAILURE);
 
   // Calculate the size for the memory region backing the canvas.
diff --git a/ui/touch_selection/touch_selection_controller.h b/ui/touch_selection/touch_selection_controller.h
index 797b755..ae0161b 100644
--- a/ui/touch_selection/touch_selection_controller.h
+++ b/ui/touch_selection/touch_selection_controller.h
@@ -66,6 +66,8 @@
 
     // Controls whether an insertion handle is shown on a tap for an empty
     // editable text. Defauls to false.
+    // TODO(mohsen): This flag used to be set to |true| on Aura. That's not the
+    // case anymore and it is always |false|. Consider removing it.
     bool show_on_tap_for_empty_editable;
   };
 
diff --git a/ui/touch_selection/touch_selection_menu_runner.h b/ui/touch_selection/touch_selection_menu_runner.h
index 8db3213..f4e05da 100644
--- a/ui/touch_selection/touch_selection_menu_runner.h
+++ b/ui/touch_selection/touch_selection_menu_runner.h
@@ -42,6 +42,10 @@
 
   static TouchSelectionMenuRunner* GetInstance();
 
+  // Checks whether there is any command available to show in the menu.
+  virtual bool IsMenuAvailable(
+      const TouchSelectionMenuClient* client) const = 0;
+
   // Creates and displays the quick menu, if there is any command available.
   // |anchor_rect| is in screen coordinates.
   virtual void OpenMenu(TouchSelectionMenuClient* client,
diff --git a/ui/views/touchui/touch_selection_menu_runner_views.cc b/ui/views/touchui/touch_selection_menu_runner_views.cc
index 55b532c..29fd56ee 100644
--- a/ui/views/touchui/touch_selection_menu_runner_views.cc
+++ b/ui/views/touchui/touch_selection_menu_runner_views.cc
@@ -38,24 +38,19 @@
 class TouchSelectionMenuRunnerViews::Menu : public BubbleDelegateView,
                                             public ButtonListener {
  public:
-  // Closes the menu. This will eventually self-destroy the object.
-  void Close();
-
-  // Returns a new instance of Menu if there is any command available;
-  // otherwise, returns |nullptr|.
-  static Menu* Create(TouchSelectionMenuRunnerViews* owner,
-                      ui::TouchSelectionMenuClient* client,
-                      const gfx::Rect& anchor_rect,
-                      const gfx::Size& handle_image_size,
-                      aura::Window* context);
-
- private:
   Menu(TouchSelectionMenuRunnerViews* owner,
        ui::TouchSelectionMenuClient* client,
        const gfx::Rect& anchor_rect,
        const gfx::Size& handle_image_size,
        aura::Window* context);
 
+  // Checks whether there is any command available to show in the menu.
+  static bool IsMenuAvailable(const ui::TouchSelectionMenuClient* client);
+
+  // Closes the menu. This will eventually self-destroy the object.
+  void Close();
+
+ private:
   ~Menu() override;
 
   // Queries the |client_| for what commands to show in the menu and sizes the
@@ -78,24 +73,6 @@
   DISALLOW_COPY_AND_ASSIGN(Menu);
 };
 
-TouchSelectionMenuRunnerViews::Menu*
-TouchSelectionMenuRunnerViews::Menu::Create(
-    TouchSelectionMenuRunnerViews* owner,
-    ui::TouchSelectionMenuClient* client,
-    const gfx::Rect& anchor_rect,
-    const gfx::Size& handle_image_size,
-    aura::Window* context) {
-  DCHECK(client);
-
-  for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
-    if (client->IsCommandIdEnabled(kMenuCommands[i]))
-      return new Menu(owner, client, anchor_rect, handle_image_size, context);
-  }
-
-  // No command is available, so return |nullptr|.
-  return nullptr;
-}
-
 TouchSelectionMenuRunnerViews::Menu::Menu(TouchSelectionMenuRunnerViews* owner,
                                           ui::TouchSelectionMenuClient* client,
                                           const gfx::Rect& anchor_rect,
@@ -136,6 +113,17 @@
   GetWidget()->Show();
 }
 
+bool TouchSelectionMenuRunnerViews::Menu::IsMenuAvailable(
+    const ui::TouchSelectionMenuClient* client) {
+  DCHECK(client);
+
+  for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
+    if (client->IsCommandIdEnabled(kMenuCommands[i]))
+      return true;
+  }
+  return false;
+}
+
 TouchSelectionMenuRunnerViews::Menu::~Menu() {
 }
 
@@ -223,6 +211,11 @@
   return menu_ ? menu_->GetAnchorRect() : gfx::Rect();
 }
 
+bool TouchSelectionMenuRunnerViews::IsMenuAvailable(
+    const ui::TouchSelectionMenuClient* client) const {
+  return TouchSelectionMenuRunnerViews::Menu::IsMenuAvailable(client);
+}
+
 void TouchSelectionMenuRunnerViews::OpenMenu(
     ui::TouchSelectionMenuClient* client,
     const gfx::Rect& anchor_rect,
@@ -230,7 +223,8 @@
     aura::Window* context) {
   CloseMenu();
 
-  menu_ = Menu::Create(this, client, anchor_rect, handle_image_size, context);
+  if (TouchSelectionMenuRunnerViews::Menu::IsMenuAvailable(client))
+    menu_ = new Menu(this, client, anchor_rect, handle_image_size, context);
 }
 
 void TouchSelectionMenuRunnerViews::CloseMenu() {
diff --git a/ui/views/touchui/touch_selection_menu_runner_views.h b/ui/views/touchui/touch_selection_menu_runner_views.h
index 46032ee..b3ba5175 100644
--- a/ui/views/touchui/touch_selection_menu_runner_views.h
+++ b/ui/views/touchui/touch_selection_menu_runner_views.h
@@ -26,6 +26,8 @@
   gfx::Rect GetAnchorRectForTest() const;
 
   // ui::TouchSelectionMenuRunner:
+  bool IsMenuAvailable(
+      const ui::TouchSelectionMenuClient* client) const override;
   void OpenMenu(ui::TouchSelectionMenuClient* client,
                 const gfx::Rect& anchor_rect,
                 const gfx::Size& handle_image_size,
diff --git a/ui/webui/resources/polymer_resources.grdp b/ui/webui/resources/polymer_resources.grdp
index ef3b25f..2ec01b8 100644
--- a/ui/webui/resources/polymer_resources.grdp
+++ b/ui/webui/resources/polymer_resources.grdp
@@ -413,9 +413,6 @@
   <structure name="IDR_POLYMER_1_0_PAPER_DRAWER_PANEL_PAPER_DRAWER_PANEL_EXTRACTED_JS"
              file="../../../third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel-extracted.js"
              type="chrome_html" />
-  <structure name="IDR_POLYMER_1_0_PAPER_DRAWER_PANEL_PAPER_DRAWER_PANEL_CSS"
-             file="../../../third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.css"
-             type="chrome_html" />
   <structure name="IDR_POLYMER_1_0_PAPER_DRAWER_PANEL_PAPER_DRAWER_PANEL_HTML"
              file="../../../third_party/polymer/v1_0/components-chromium/paper-drawer-panel/paper-drawer-panel.html"
              type="chrome_html" />
@@ -569,12 +566,12 @@
   <structure name="IDR_POLYMER_1_0_PAPER_SPINNER_PAPER_SPINNER_EXTRACTED_JS"
              file="../../../third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-extracted.js"
              type="chrome_html" />
-  <structure name="IDR_POLYMER_1_0_PAPER_SPINNER_PAPER_SPINNER_CSS"
-             file="../../../third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.css"
-             type="chrome_html" />
   <structure name="IDR_POLYMER_1_0_PAPER_SPINNER_PAPER_SPINNER_HTML"
              file="../../../third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner.html"
              type="chrome_html" />
+  <structure name="IDR_POLYMER_1_0_PAPER_SPINNER_PAPER_SPINNER_STYLES_HTML"
+             file="../../../third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-styles.html"
+             type="chrome_html" />
   <structure name="IDR_POLYMER_1_0_PAPER_STYLES_CLASSES_SHADOW_LAYOUT_HTML"
              file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/classes/shadow-layout.html"
              type="chrome_html" />
@@ -657,4 +654,3 @@
              file="../../../third_party/web-animations-js/sources/web-animations-next-lite.min.js"
              type="chrome_html" />
 </grit-part>
-